From 3102a3343b3acf4663cebdaf0f1cc9e7e9031c8c Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Thu, 19 Nov 2020 14:43:08 +0000 Subject: [PATCH] Added rollback case to the transaction block example --- docs/usage.rst | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/usage.rst b/docs/usage.rst index c3694f559..c985163ee 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -163,7 +163,7 @@ a `~rollback()` is called. If a database operation fails with an error message such as *InFailedSqlTransaction: current transaction is aborted, commands ignored until end of transaction block*, it means that **a previous operation - failed** and the database session is in a state on error. You need to call + failed** and the database session is in a state of error. You need to call `!rollback()` if you want to keep on using the same connection. The manual commit requirement can be suspended using `~Connection.autocommit`, @@ -207,6 +207,21 @@ accounts unbalanced: # The transaction is now committed +But because the bank is, like, *extremely secure*, they also verify that no +account goes negative: + +.. code:: python + + def move_money(conn, account, amount): + new_balance = add_to_balance(conn, account, amount) + if new_balance < 0: + raise ValueError("account balance cannot go negative") + +In case this function raises an exception, be it the `!ValueError` in the +example or any other exception expected or not, the transaction will be rolled +back, and the exception will propagate out of the `with` block, further down +the call stack. + Transaction blocks can also be nested (internal transaction blocks are implemented using SAVEPOINT__): an exception raised inside an inner block has a chance of being handled and not completely fail outer operations. The -- 2.47.3