From 0dfe913803794e7c299fe961a7ded520415a868a Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Mon, 19 Nov 2001 23:17:38 +0000 Subject: [PATCH] Fill in empty tutorial section about transactions. --- doc/src/sgml/advanced.sgml | 106 ++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/advanced.sgml b/doc/src/sgml/advanced.sgml index 165f9d1c8e4..4d15368683e 100644 --- a/doc/src/sgml/advanced.sgml +++ b/doc/src/sgml/advanced.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/advanced.sgml,v 1.23 2001/11/19 05:37:53 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/advanced.sgml,v 1.24 2001/11/19 23:17:38 tgl Exp $ --> <chapter id="tutorial-advanced"> @@ -143,11 +143,113 @@ ERROR: <unnamed> referential integrity violation - key referenced from we <sect1 id="tutorial-transactions"> <title>Transactions</title> - <comment>This section needs to be written.</comment> + <indexterm zone="tutorial-transactions"> + <primary>transactions</primary> + </indexterm> + + <para> + <firstterm>Transactions</> are a fundamental concept of all database + systems. The essential point of a transaction is that it bundles + multiple steps into a single, all-or-nothing operation. The intermediate + states between the steps are not visible to other concurrent transactions, + and if some failure occurs that prevents the transaction from completing, + then none of the steps affect the database at all. + </para> + + <para> + For example, consider a bank database that contains balances for various + customer accounts, as well as total deposit balances for branches. + Suppose that we want to record a payment of $100.00 from Alice's account + to Bob's account. Simplifying outrageously, the SQL commands for this + might look like +<programlisting> +UPDATE accounts SET balance = balance - 100.00 + WHERE name = 'Alice'; +UPDATE branches SET balance = balance - 100.00 + WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Alice'); +UPDATE accounts SET balance = balance + 100.00 + WHERE name = 'Bob'; +UPDATE branches SET balance = balance + 100.00 + WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Bob'); +</programlisting> + The details of these commands are not important here; the important + point is that there are several separate updates involved to accomplish + this rather simple operation. Our bank's officers will want to be + assured that either all these updates happen, or none of them happen. + It would certainly not do for a system failure to result in Bob + receiving $100.00 that was not debited from Alice. Nor would Alice long + remain a happy customer if she was debited without Bob being credited. + We need a guarantee that if something goes wrong partway through the + operation, none of the steps executed so far will take effect. Grouping + the updates into a <firstterm>transaction</> gives us this guarantee. + A transaction is said to be <firstterm>atomic</>: from the point of + view of other transactions, it either happens completely or not at all. + </para> + + <para> + We also want a + guarantee that once a transaction is completed and acknowledged by + the database system, it has indeed been permanently recorded + and won't be lost even if a crash ensues shortly thereafter. + For example, if we are recording a cash withdrawal by Bob, + we do not want any chance that the debit to his account will + disappear in a crash just as he walks out the bank door. + A transactional database guarantees that all the updates made by + a transaction are logged in permanent storage (i.e., on disk) before + the transaction is reported complete. + </para> + + <para> + Another important property of transactional databases is closely + related to the notion of atomic updates: when multiple transactions + are running concurrently, each one should not be able to see the + incomplete changes made by others. For example, if one transaction + is busy totalling all the branch balances, it would not do for it + to include the debit from Alice's branch but not the credit to + Bob's branch, nor vice versa. So transactions must be all-or-nothing + not only in terms of their permanent effect on the database, but + also in terms of their visibility as they happen. The updates made + so far by an open transaction are invisible to other transactions + until the transaction completes, whereupon all the updates become + visible simultaneously. + </para> <para> + In <productname>Postgres</>, a transaction is set up by surrounding + the SQL commands of the transaction with + <command>BEGIN</> and <command>COMMIT</> commands. So our banking + transaction would actually look like +<programlisting> +BEGIN; +UPDATE accounts SET balance = balance - 100.00 + WHERE name = 'Alice'; +-- etc etc +COMMIT; +</programlisting> + If, partway through the transaction, we decide we don't want to + commit (perhaps we just noticed that Alice's balance went negative), + we can issue the command <command>ROLLBACK</> instead of + <command>COMMIT</>, and all our updates so far will be canceled. + </para> + <para> + <productname>Postgres</> actually treats every SQL statement as being + executed within a transaction. If you don't issue a <command>BEGIN</> + command, + then each individual statement has an implicit <command>BEGIN</> and + (if successful) <command>COMMIT</> wrapped around it. A group of + statements surrounded by <command>BEGIN</> and <command>COMMIT</> + is sometimes called a <firstterm>transaction block</>. </para> + + <note> + <para> + Some client libraries issue <command>BEGIN</> and <command>COMMIT</> + commands automatically, so that you may get the effect of transaction + blocks without asking. Check the documentation for the interface + you are using. + </para> + </note> </sect1> -- GitLab