62 lines
2.2 KiB
Python
62 lines
2.2 KiB
Python
# This test verifies behavior when traversing an update chain during
|
|
# locking an old version of the tuple. There are three tests here:
|
|
# 1. update the tuple, then delete it; a second transaction locks the
|
|
# first version. This should raise an error if the DELETE succeeds,
|
|
# but be allowed to continue if it aborts.
|
|
# 2. Same as (1), except that instead of deleting the tuple, we merely
|
|
# update its key. The behavior should be the same as for (1).
|
|
# 3. Same as (2), except that we update the tuple without modifying its
|
|
# key. In this case, no error should be raised.
|
|
# When run in REPEATABLE READ or SERIALIZABLE transaction isolation levels, all
|
|
# permutations that commit s2 cause a serializability error; all permutations
|
|
# that rollback s2 can get through.
|
|
#
|
|
# We use an advisory lock (which is locked during s1's setup) to let s2 obtain
|
|
# its snapshot early and only allow it to actually traverse the update chain
|
|
# when s1 is done creating it.
|
|
|
|
setup
|
|
{
|
|
DROP TABLE IF EXISTS foo;
|
|
CREATE TABLE foo (
|
|
key int PRIMARY KEY,
|
|
value int
|
|
);
|
|
|
|
INSERT INTO foo VALUES (1, 1);
|
|
}
|
|
|
|
teardown
|
|
{
|
|
DROP TABLE foo;
|
|
}
|
|
|
|
session s1
|
|
# obtain lock on the tuple, traversing its update chain
|
|
step s1l { SELECT * FROM foo WHERE pg_advisory_xact_lock(0) IS NOT NULL AND key = 1 FOR KEY SHARE; }
|
|
|
|
session s2
|
|
setup { SELECT pg_advisory_lock(0); }
|
|
step s2b { BEGIN; }
|
|
step s2u { UPDATE foo SET value = 2 WHERE key = 1; }
|
|
step s2_blocker1 { DELETE FROM foo; }
|
|
step s2_blocker2 { UPDATE foo SET key = 2 WHERE key = 1; }
|
|
step s2_blocker3 { UPDATE foo SET value = 2 WHERE key = 1; }
|
|
step s2_unlock { SELECT pg_advisory_unlock(0); }
|
|
step s2c { COMMIT; }
|
|
step s2r { ROLLBACK; }
|
|
|
|
permutation s2b s1l s2u s2_blocker1 s2_unlock s2c
|
|
permutation s2b s1l s2u s2_blocker2 s2_unlock s2c
|
|
permutation s2b s1l s2u s2_blocker3 s2_unlock s2c
|
|
permutation s2b s1l s2u s2_blocker1 s2_unlock s2r
|
|
permutation s2b s1l s2u s2_blocker2 s2_unlock s2r
|
|
permutation s2b s1l s2u s2_blocker3 s2_unlock s2r
|
|
|
|
permutation s2b s1l s2u s2_blocker1 s2c s2_unlock
|
|
permutation s2b s1l s2u s2_blocker2 s2c s2_unlock
|
|
permutation s2b s1l s2u s2_blocker3 s2c s2_unlock
|
|
permutation s2b s1l s2u s2_blocker1 s2r s2_unlock
|
|
permutation s2b s1l s2u s2_blocker2 s2r s2_unlock
|
|
permutation s2b s1l s2u s2_blocker3 s2r s2_unlock
|