📄 transactions.out
字号:
---- TRANSACTIONS--BEGIN;SELECT * INTO TABLE xacttest FROM aggtest;INSERT INTO xacttest (a, b) VALUES (777, 777.777);END;-- should retrieve one value--SELECT a FROM xacttest WHERE a > 100; a ----- 777(1 row)BEGIN;CREATE TABLE disappear (a int4);DELETE FROM aggtest;-- should be emptySELECT * FROM aggtest; a | b ---+---(0 rows)ABORT;-- should not exist SELECT oid FROM pg_class WHERE relname = 'disappear'; oid -----(0 rows)-- should have members again SELECT * FROM aggtest; a | b -----+--------- 56 | 7.8 100 | 99.097 0 | 0.09561 42 | 324.78(4 rows)-- Read-only testsCREATE TABLE writetest (a int);CREATE TEMPORARY TABLE temptest (a int);SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY;DROP TABLE writetest; -- failERROR: transaction is read-onlyINSERT INTO writetest VALUES (1); -- failERROR: transaction is read-onlySELECT * FROM writetest; -- ok a ---(0 rows)DELETE FROM temptest; -- okUPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a; -- okPREPARE test AS UPDATE writetest SET a = 0; -- okEXECUTE test; -- failERROR: transaction is read-onlySELECT * FROM writetest, temptest; -- ok a | a ---+---(0 rows)CREATE TABLE test AS SELECT * FROM writetest; -- failERROR: transaction is read-onlySTART TRANSACTION READ WRITE;DROP TABLE writetest; -- okCOMMIT;-- Subtransactions, basic tests-- create & drop tablesSET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE;CREATE TABLE foobar (a int);BEGIN; CREATE TABLE foo (a int); SAVEPOINT one; DROP TABLE foo; CREATE TABLE bar (a int); ROLLBACK TO SAVEPOINT one; RELEASE SAVEPOINT one; SAVEPOINT two; CREATE TABLE baz (a int); RELEASE SAVEPOINT two; drop TABLE foobar; CREATE TABLE barbaz (a int);COMMIT;-- should exist: barbaz, baz, fooSELECT * FROM foo; -- should be empty a ---(0 rows)SELECT * FROM bar; -- shouldn't existERROR: relation "bar" does not existSELECT * FROM barbaz; -- should be empty a ---(0 rows)SELECT * FROM baz; -- should be empty a ---(0 rows)-- insertsBEGIN; INSERT INTO foo VALUES (1); SAVEPOINT one; INSERT into bar VALUES (1);ERROR: relation "bar" does not exist ROLLBACK TO one; RELEASE SAVEPOINT one; SAVEPOINT two; INSERT into barbaz VALUES (1); RELEASE two; SAVEPOINT three; SAVEPOINT four; INSERT INTO foo VALUES (2); RELEASE SAVEPOINT four; ROLLBACK TO SAVEPOINT three; RELEASE SAVEPOINT three; INSERT INTO foo VALUES (3);COMMIT;SELECT * FROM foo; -- should have 1 and 3 a --- 1 3(2 rows)SELECT * FROM barbaz; -- should have 1 a --- 1(1 row)-- test whole-tree commitBEGIN; SAVEPOINT one; SELECT foo;ERROR: column "foo" does not exist ROLLBACK TO SAVEPOINT one; RELEASE SAVEPOINT one; SAVEPOINT two; CREATE TABLE savepoints (a int); SAVEPOINT three; INSERT INTO savepoints VALUES (1); SAVEPOINT four; INSERT INTO savepoints VALUES (2); SAVEPOINT five; INSERT INTO savepoints VALUES (3); ROLLBACK TO SAVEPOINT five;COMMIT;COMMIT; -- should not be in a transaction blockWARNING: there is no transaction in progressSELECT * FROM savepoints; a --- 1 2(2 rows)-- test whole-tree rollbackBEGIN; SAVEPOINT one; DELETE FROM savepoints WHERE a=1; RELEASE SAVEPOINT one; SAVEPOINT two; DELETE FROM savepoints WHERE a=1; SAVEPOINT three; DELETE FROM savepoints WHERE a=2;ROLLBACK;COMMIT; -- should not be in a transaction blockWARNING: there is no transaction in progress SELECT * FROM savepoints; a --- 1 2(2 rows)-- test whole-tree commit on an aborted subtransactionBEGIN; INSERT INTO savepoints VALUES (4); SAVEPOINT one; INSERT INTO savepoints VALUES (5); SELECT foo;ERROR: column "foo" does not existCOMMIT;SELECT * FROM savepoints; a --- 1 2(2 rows)BEGIN; INSERT INTO savepoints VALUES (6); SAVEPOINT one; INSERT INTO savepoints VALUES (7); RELEASE SAVEPOINT one; INSERT INTO savepoints VALUES (8);COMMIT;-- rows 6 and 8 should have been created by the same xactSELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=8; ?column? ---------- t(1 row)-- rows 6 and 7 should have been created by different xactsSELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=7; ?column? ---------- f(1 row)BEGIN; INSERT INTO savepoints VALUES (9); SAVEPOINT one; INSERT INTO savepoints VALUES (10); ROLLBACK TO SAVEPOINT one; INSERT INTO savepoints VALUES (11);COMMIT;SELECT a FROM savepoints WHERE a in (9, 10, 11); a ---- 9 11(2 rows)-- rows 9 and 11 should have been created by different xactsSELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=9 AND b.a=11; ?column? ---------- f(1 row)BEGIN; INSERT INTO savepoints VALUES (12); SAVEPOINT one; INSERT INTO savepoints VALUES (13); SAVEPOINT two; INSERT INTO savepoints VALUES (14); ROLLBACK TO SAVEPOINT one; INSERT INTO savepoints VALUES (15); SAVEPOINT two; INSERT INTO savepoints VALUES (16); SAVEPOINT three; INSERT INTO savepoints VALUES (17);COMMIT;SELECT a FROM savepoints WHERE a BETWEEN 12 AND 17; a ---- 12 15 16 17(4 rows)BEGIN; INSERT INTO savepoints VALUES (18); SAVEPOINT one; INSERT INTO savepoints VALUES (19); SAVEPOINT two; INSERT INTO savepoints VALUES (20); ROLLBACK TO SAVEPOINT one; INSERT INTO savepoints VALUES (21); ROLLBACK TO SAVEPOINT one; INSERT INTO savepoints VALUES (22);COMMIT;SELECT a FROM savepoints WHERE a BETWEEN 18 AND 22; a ---- 18 22(2 rows)DROP TABLE savepoints;-- only in a transaction block:SAVEPOINT one;ERROR: SAVEPOINT may only be used in transaction blocksROLLBACK TO SAVEPOINT one;ERROR: ROLLBACK TO SAVEPOINT may only be used in transaction blocksRELEASE SAVEPOINT one;ERROR: RELEASE SAVEPOINT may only be used in transaction blocks-- Only "rollback to" allowed in aborted stateBEGIN; SAVEPOINT one; SELECT 0/0;ERROR: division by zero SAVEPOINT two; -- ignored till the end of ...ERROR: current transaction is aborted, commands ignored until end of transaction block RELEASE SAVEPOINT one; -- ignored till the end of ...ERROR: current transaction is aborted, commands ignored until end of transaction block ROLLBACK TO SAVEPOINT one; SELECT 1; ?column? ---------- 1(1 row)COMMIT;SELECT 1; -- this should work ?column? ---------- 1(1 row)-- check non-transactional behavior of cursorsBEGIN; DECLARE c CURSOR FOR SELECT unique2 FROM tenk1; SAVEPOINT one; FETCH 10 FROM c; unique2 --------- 0 1 2 3 4 5 6 7 8 9(10 rows) ROLLBACK TO SAVEPOINT one; FETCH 10 FROM c; unique2 --------- 10 11 12 13 14 15 16 17 18 19(10 rows) RELEASE SAVEPOINT one; FETCH 10 FROM c; unique2 --------- 20 21 22 23 24 25 26 27 28 29(10 rows) CLOSE c; DECLARE c CURSOR FOR SELECT unique2/0 FROM tenk1; SAVEPOINT two; FETCH 10 FROM c;ERROR: division by zero ROLLBACK TO SAVEPOINT two; -- c is now dead to the world ... FETCH 10 FROM c;ERROR: portal "c" cannot be run ROLLBACK TO SAVEPOINT two; RELEASE SAVEPOINT two; FETCH 10 FROM c;ERROR: portal "c" cannot be runCOMMIT;---- Check that "stable" functions are really stable. They should not be-- able to see the partial results of the calling query. (Ideally we would-- also check that they don't see commits of concurrent transactions, but-- that's a mite hard to do within the limitations of pg_regress.)--select * from xacttest; a | b -----+--------- 56 | 7.8 100 | 99.097 0 | 0.09561 42 | 324.78 777 | 777.777(5 rows)create or replace function max_xacttest() returns smallint language sql as'select max(a) from xacttest' stable;begin;update xacttest set a = max_xacttest() + 10 where a > 0;select * from xacttest; a | b -----+--------- 0 | 0.09561 787 | 7.8 787 | 99.097 787 | 324.78 787 | 777.777(5 rows)rollback;-- But a volatile function can see the partial results of the calling querycreate or replace function max_xacttest() returns smallint language sql as'select max(a) from xacttest' volatile;begin;update xacttest set a = max_xacttest() + 10 where a > 0;select * from xacttest; a | b -----+--------- 0 | 0.09561 787 | 7.8 797 | 99.097 807 | 324.78 817 | 777.777(5 rows)rollback;-- Now the same test with plpgsql (since it depends on SPI which is different)create or replace function max_xacttest() returns smallint language plpgsql as'begin return max(a) from xacttest; end' stable;begin;update xacttest set a = max_xacttest() + 10 where a > 0;select * from xacttest; a | b -----+--------- 0 | 0.09561 787 | 7.8 787 | 99.097 787 | 324.78 787 | 777.777(5 rows)rollback;create or replace function max_xacttest() returns smallint language plpgsql as'begin return max(a) from xacttest; end' volatile;begin;update xacttest set a = max_xacttest() + 10 where a > 0;select * from xacttest; a | b -----+--------- 0 | 0.09561 787 | 7.8 797 | 99.097 807 | 324.78 817 | 777.777(5 rows)rollback;-- test case for problems with dropping an open relation during abortBEGIN; savepoint x; CREATE TABLE koju (a INT UNIQUE);NOTICE: CREATE TABLE / UNIQUE will create implicit index "koju_a_key" for table "koju" INSERT INTO koju VALUES (1); INSERT INTO koju VALUES (1);ERROR: duplicate key violates unique constraint "koju_a_key" rollback to x; CREATE TABLE koju (a INT UNIQUE);NOTICE: CREATE TABLE / UNIQUE will create implicit index "koju_a_key" for table "koju" INSERT INTO koju VALUES (1); INSERT INTO koju VALUES (1);ERROR: duplicate key violates unique constraint "koju_a_key"ROLLBACK;DROP TABLE foo;DROP TABLE baz;DROP TABLE barbaz;-- verify that cursors created during an aborted subtransaction are-- closed, but that we do not rollback the effect of any FETCHs-- performed in the aborted subtransactionbegin;savepoint x;create table abc (a int);insert into abc values (5);insert into abc values (10);declare foo cursor for select * from abc;fetch from foo; a --- 5(1 row)rollback to x;-- should failfetch from foo;ERROR: cursor "foo" does not existcommit;begin;create table abc (a int);insert into abc values (5);insert into abc values (10);insert into abc values (15);declare foo cursor for select * from abc;fetch from foo; a --- 5(1 row)savepoint x;fetch from foo; a ---- 10(1 row)rollback to x;fetch from foo; a ---- 15(1 row)abort;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -