mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
Fill in empty tutorial section about transactions.
This commit is contained in:
parent
09634eafe1
commit
0dfe913803
@ -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>
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user