-- -- PREPARED TRANSACTIONS (two-phase commit) -- -- We can't readily test persistence of prepared xacts within the -- regression script framework, unfortunately. Note that a crash -- isn't really needed ... stopping and starting the postmaster would -- be enough, but we can't even do that here.
-- create a simple table that we'll use in the tests CREATETABLE pxtest1 (foobar VARCHAR(10));
INSERTINTO pxtest1 VALUES ('aaa');
-- Test PREPARE TRANSACTION
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; UPDATE pxtest1 SET foobar = 'bbb'WHERE foobar = 'aaa'; SELECT * FROM pxtest1;
PREPARE TRANSACTION 'regress_foo1';
SELECT * FROM pxtest1;
-- Test pg_prepared_xacts system view SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
-- Test ROLLBACK PREPARED
ROLLBACK PREPARED 'regress_foo1';
SELECT * FROM pxtest1;
SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
-- Test COMMIT PREPARED
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; INSERTINTO pxtest1 VALUES ('ddd'); SELECT * FROM pxtest1;
PREPARE TRANSACTION 'regress_foo2';
SELECT * FROM pxtest1;
COMMIT PREPARED 'regress_foo2';
SELECT * FROM pxtest1;
-- Test duplicate gids
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; UPDATE pxtest1 SET foobar = 'eee'WHERE foobar = 'ddd'; SELECT * FROM pxtest1;
PREPARE TRANSACTION 'regress_foo3';
SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; INSERTINTO pxtest1 VALUES ('fff');
-- This should fail, because the gid foo3 is already in use
PREPARE TRANSACTION 'regress_foo3';
SELECT * FROM pxtest1;
ROLLBACK PREPARED 'regress_foo3';
SELECT * FROM pxtest1;
-- Test serialization failure (SSI)
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; UPDATE pxtest1 SET foobar = 'eee'WHERE foobar = 'ddd'; SELECT * FROM pxtest1;
PREPARE TRANSACTION 'regress_foo4';
SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT * FROM pxtest1;
-- This should fail, because the two transactions have a write-skew anomaly INSERTINTO pxtest1 VALUES ('fff');
PREPARE TRANSACTION 'regress_foo5';
SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
ROLLBACK PREPARED 'regress_foo4';
SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
-- Clean up DROPTABLE pxtest1;
-- Test detection of session-level and xact-level locks on same object
BEGIN; SELECT pg_advisory_lock(1); SELECT pg_advisory_xact_lock_shared(1);
PREPARE TRANSACTION 'regress_foo6'; -- fails
-- Test subtransactions
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; CREATETABLE pxtest2 (a int); INSERTINTO pxtest2 VALUES (1);
SAVEPOINT a; INSERTINTO pxtest2 VALUES (2);
ROLLBACK TO a;
SAVEPOINT b; INSERTINTO pxtest2 VALUES (3);
PREPARE TRANSACTION 'regress_sub1';
CREATETABLE pxtest3(fff int);
-- Test shared invalidation
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; DROPTABLE pxtest3; CREATETABLE pxtest4 (a int); INSERTINTO pxtest4 VALUES (1); INSERTINTO pxtest4 VALUES (2); DECLARE foo CURSORFORSELECT * FROM pxtest4; -- Fetch 1 tuple, keeping the cursor open FETCH1FROM foo;
PREPARE TRANSACTION 'regress_sub2';
-- No such cursor FETCH1FROM foo;
-- Table doesn't exist, the creation hasn't been committed yet SELECT * FROM pxtest2;
-- There should be two prepared transactions SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
-- pxtest3 should be locked because of the pending DROP
begin; locktable pxtest3 in access share mode nowait;
rollback;
-- Disconnect, we will continue testing in a different backend
\c -
-- There should still be two prepared transactions SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
-- pxtest3 should still be locked because of the pending DROP
begin; locktable pxtest3 in access share mode nowait;
rollback;
-- There should be one prepared transaction SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
-- Commit table drop COMMIT PREPARED 'regress_sub2'; SELECT * FROM pxtest3;
-- There should be no prepared transactions SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_'ORDERBY gid;
-- Test row-level locks held by prepared transactions CREATETABLE pxtest_rowlock (id intPRIMARYKEY, data text); INSERTINTO pxtest_rowlock VALUES (1, 'test data');
BEGIN; SELECT * FROM pxtest_rowlock WHERE id = 1FOR SHARE;
PREPARE TRANSACTION 'regress_p1';
-- Should fail because the row is locked SELECT * FROM pxtest_rowlock WHERE id = 1FORUPDATE NOWAIT;
-- Test prepared transactions that participate in multixacts. For -- that, lock the same row again, creating a multixid.
BEGIN; SELECT * FROM pxtest_rowlock WHERE id = 1FOR SHARE;
PREPARE TRANSACTION 'regress_p2';
-- Should fail because the row is locked SELECT * FROM pxtest_rowlock WHERE id = 1FORUPDATE NOWAIT;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.