1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Transaction chaining

Add command variants COMMIT AND CHAIN and ROLLBACK AND CHAIN, which
start new transactions with the same transaction characteristics as the
just finished one, per SQL standard.

Support for transaction chaining in PL/pgSQL is also added.  This
functionality is especially useful when running COMMIT in a loop in
PL/pgSQL.

Reviewed-by: Fabien COELHO <coelho@cri.ensmp.fr>
Discussion: https://www.postgresql.org/message-id/flat/28536681-324b-10dc-ade8-ab46f7645a5a@2ndquadrant.com
This commit is contained in:
Peter Eisentraut
2019-03-24 10:33:14 +01:00
parent b2db277057
commit 280a408b48
26 changed files with 601 additions and 38 deletions

View File

@ -659,6 +659,197 @@ ERROR: portal "ctt" cannot be run
COMMIT;
DROP FUNCTION create_temp_tab();
DROP FUNCTION invert(x float8);
-- Tests for AND CHAIN
CREATE TABLE abc (a int);
-- set nondefault value so we have something to override below
SET default_transaction_read_only = on;
START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE;
SHOW transaction_isolation;
transaction_isolation
-----------------------
repeatable read
(1 row)
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SHOW transaction_deferrable;
transaction_deferrable
------------------------
on
(1 row)
INSERT INTO abc VALUES (1);
INSERT INTO abc VALUES (2);
COMMIT AND CHAIN; -- TBLOCK_END
SHOW transaction_isolation;
transaction_isolation
-----------------------
repeatable read
(1 row)
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SHOW transaction_deferrable;
transaction_deferrable
------------------------
on
(1 row)
INSERT INTO abc VALUES ('error');
ERROR: invalid input syntax for type integer: "error"
LINE 1: INSERT INTO abc VALUES ('error');
^
INSERT INTO abc VALUES (3); -- check it's really aborted
ERROR: current transaction is aborted, commands ignored until end of transaction block
COMMIT AND CHAIN; -- TBLOCK_ABORT_END
SHOW transaction_isolation;
transaction_isolation
-----------------------
repeatable read
(1 row)
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SHOW transaction_deferrable;
transaction_deferrable
------------------------
on
(1 row)
INSERT INTO abc VALUES (4);
COMMIT;
START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE;
SHOW transaction_isolation;
transaction_isolation
-----------------------
repeatable read
(1 row)
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SHOW transaction_deferrable;
transaction_deferrable
------------------------
on
(1 row)
SAVEPOINT x;
INSERT INTO abc VALUES ('error');
ERROR: invalid input syntax for type integer: "error"
LINE 1: INSERT INTO abc VALUES ('error');
^
COMMIT AND CHAIN; -- TBLOCK_ABORT_PENDING
SHOW transaction_isolation;
transaction_isolation
-----------------------
repeatable read
(1 row)
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SHOW transaction_deferrable;
transaction_deferrable
------------------------
on
(1 row)
INSERT INTO abc VALUES (5);
COMMIT;
-- different mix of options just for fun
START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE;
SHOW transaction_isolation;
transaction_isolation
-----------------------
serializable
(1 row)
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SHOW transaction_deferrable;
transaction_deferrable
------------------------
off
(1 row)
INSERT INTO abc VALUES (6);
ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING
SHOW transaction_isolation;
transaction_isolation
-----------------------
serializable
(1 row)
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SHOW transaction_deferrable;
transaction_deferrable
------------------------
off
(1 row)
INSERT INTO abc VALUES ('error');
ERROR: invalid input syntax for type integer: "error"
LINE 1: INSERT INTO abc VALUES ('error');
^
ROLLBACK AND CHAIN; -- TBLOCK_ABORT_END
SHOW transaction_isolation;
transaction_isolation
-----------------------
serializable
(1 row)
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SHOW transaction_deferrable;
transaction_deferrable
------------------------
off
(1 row)
ROLLBACK;
SELECT * FROM abc ORDER BY 1;
a
---
1
2
4
5
(4 rows)
RESET default_transaction_read_only;
DROP TABLE abc;
-- Test assorted behaviors around the implicit transaction block created
-- when multiple SQL commands are sent in a single Query message. These
-- tests rely on the fact that psql will not break SQL commands apart at a

View File

@ -419,6 +419,69 @@ DROP FUNCTION create_temp_tab();
DROP FUNCTION invert(x float8);
-- Tests for AND CHAIN
CREATE TABLE abc (a int);
-- set nondefault value so we have something to override below
SET default_transaction_read_only = on;
START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE;
SHOW transaction_isolation;
SHOW transaction_read_only;
SHOW transaction_deferrable;
INSERT INTO abc VALUES (1);
INSERT INTO abc VALUES (2);
COMMIT AND CHAIN; -- TBLOCK_END
SHOW transaction_isolation;
SHOW transaction_read_only;
SHOW transaction_deferrable;
INSERT INTO abc VALUES ('error');
INSERT INTO abc VALUES (3); -- check it's really aborted
COMMIT AND CHAIN; -- TBLOCK_ABORT_END
SHOW transaction_isolation;
SHOW transaction_read_only;
SHOW transaction_deferrable;
INSERT INTO abc VALUES (4);
COMMIT;
START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE;
SHOW transaction_isolation;
SHOW transaction_read_only;
SHOW transaction_deferrable;
SAVEPOINT x;
INSERT INTO abc VALUES ('error');
COMMIT AND CHAIN; -- TBLOCK_ABORT_PENDING
SHOW transaction_isolation;
SHOW transaction_read_only;
SHOW transaction_deferrable;
INSERT INTO abc VALUES (5);
COMMIT;
-- different mix of options just for fun
START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE;
SHOW transaction_isolation;
SHOW transaction_read_only;
SHOW transaction_deferrable;
INSERT INTO abc VALUES (6);
ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING
SHOW transaction_isolation;
SHOW transaction_read_only;
SHOW transaction_deferrable;
INSERT INTO abc VALUES ('error');
ROLLBACK AND CHAIN; -- TBLOCK_ABORT_END
SHOW transaction_isolation;
SHOW transaction_read_only;
SHOW transaction_deferrable;
ROLLBACK;
SELECT * FROM abc ORDER BY 1;
RESET default_transaction_read_only;
DROP TABLE abc;
-- Test assorted behaviors around the implicit transaction block created
-- when multiple SQL commands are sent in a single Query message. These
-- tests rely on the fact that psql will not break SQL commands apart at a