]> begriffs open source - ai-pg/blob - full-docs/src/sgml/html/plpgsql-transactions.html
WIP: toc builder
[ai-pg] / full-docs / src / sgml / html / plpgsql-transactions.html
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>41.8. Transaction Management</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-cursors.html" title="41.7. Cursors" /><link rel="next" href="plpgsql-errors-and-messages.html" title="41.9. Errors and Messages" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">41.8. Transaction Management</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-cursors.html" title="41.7. Cursors">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 41. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 41. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-errors-and-messages.html" title="41.9. Errors and Messages">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-TRANSACTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">41.8. Transaction Management <a href="#PLPGSQL-TRANSACTIONS" class="id_link">#</a></h2></div></div></div><p>
3     In procedures invoked by the <code class="command">CALL</code> command
4     as well as in anonymous code blocks (<code class="command">DO</code> command),
5     it is possible to end transactions using the
6     commands <code class="command">COMMIT</code> and <code class="command">ROLLBACK</code>.  A new
7     transaction is started automatically after a transaction is ended using
8     these commands, so there is no separate <code class="command">START
9     TRANSACTION</code> command.  (Note that <code class="command">BEGIN</code> and
10     <code class="command">END</code> have different meanings in PL/pgSQL.)
11    </p><p>
12     Here is a simple example:
13 </p><pre class="programlisting">
14 CREATE PROCEDURE transaction_test1()
15 LANGUAGE plpgsql
16 AS $$
17 BEGIN
18     FOR i IN 0..9 LOOP
19         INSERT INTO test1 (a) VALUES (i);
20         IF i % 2 = 0 THEN
21             COMMIT;
22         ELSE
23             ROLLBACK;
24         END IF;
25     END LOOP;
26 END;
27 $$;
28
29 CALL transaction_test1();
30 </pre><p>
31    </p><a id="id-1.8.8.10.4" class="indexterm"></a><p id="PLPGSQL-TRANSACTION-CHAIN">
32     A new transaction starts out with default transaction characteristics such
33     as transaction isolation level.  In cases where transactions are committed
34     in a loop, it might be desirable to start new transactions automatically
35     with the same characteristics as the previous one.  The commands
36     <code class="command">COMMIT AND CHAIN</code> and <code class="command">ROLLBACK AND
37     CHAIN</code> accomplish this.
38    </p><p>
39     Transaction control is only possible in <code class="command">CALL</code> or
40     <code class="command">DO</code> invocations from the top level or nested
41     <code class="command">CALL</code> or <code class="command">DO</code> invocations without any
42     other intervening command.  For example, if the call stack is
43     <code class="command">CALL proc1()</code> → <code class="command">CALL proc2()</code>
44     → <code class="command">CALL proc3()</code>, then the second and third
45     procedures can perform transaction control actions.  But if the call stack
46     is <code class="command">CALL proc1()</code> → <code class="command">SELECT
47     func2()</code> → <code class="command">CALL proc3()</code>, then the last
48     procedure cannot do transaction control, because of the
49     <code class="command">SELECT</code> in between.
50    </p><p>
51     <span class="application">PL/pgSQL</span> does not support savepoints
52     (<code class="command">SAVEPOINT</code>/<code class="command">ROLLBACK TO
53     SAVEPOINT</code>/<code class="command">RELEASE SAVEPOINT</code> commands).
54     Typical usage patterns for savepoints can be replaced by blocks with
55     exception handlers (see <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING" title="41.6.8. Trapping Errors">Section 41.6.8</a>).
56     Under the hood, a block with exception handlers forms a
57     subtransaction, which means that transactions cannot be ended inside
58     such a block.
59    </p><p>
60     Special considerations apply to cursor loops.  Consider this example:
61 </p><pre class="programlisting">
62 CREATE PROCEDURE transaction_test2()
63 LANGUAGE plpgsql
64 AS $$
65 DECLARE
66     r RECORD;
67 BEGIN
68     FOR r IN SELECT * FROM test2 ORDER BY x LOOP
69         INSERT INTO test1 (a) VALUES (r.x);
70         COMMIT;
71     END LOOP;
72 END;
73 $$;
74
75 CALL transaction_test2();
76 </pre><p>
77     Normally, cursors are automatically closed at transaction commit.
78     However, a cursor created as part of a loop like this is automatically
79     converted to a holdable cursor by the first <code class="command">COMMIT</code> or
80     <code class="command">ROLLBACK</code>.  That means that the cursor is fully
81     evaluated at the first <code class="command">COMMIT</code> or
82     <code class="command">ROLLBACK</code> rather than row by row.  The cursor is still
83     removed automatically after the loop, so this is mostly invisible to the
84     user.  But one must keep in mind that any table or row locks taken by
85     the cursor's query will no longer be held after the
86     first <code class="command">COMMIT</code> or
87     <code class="command">ROLLBACK</code>.
88    </p><p>
89     Transaction commands are not allowed in cursor loops driven by commands
90     that are not read-only (for example <code class="command">UPDATE
91     ... RETURNING</code>).
92    </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-cursors.html" title="41.7. Cursors">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 41. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-errors-and-messages.html" title="41.9. Errors and Messages">Next</a></td></tr><tr><td width="40%" align="left" valign="top">41.7. Cursors </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 41.9. Errors and Messages</td></tr></table></div></body></html>