PostgreSQL トランザクション分離レベル
v9.6 2017/7
Serializable (直列化)
※ 一つのトランザクションだけが更新系SQLを実行できる。
Case1
Case2
Serializable (直列化)
※ 一つのトランザクションだけが更新系SQLを実行できる。
Case1
Transaction 1
testdb=# BEGIN; BEGIN testdb=# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET testdb=# SELECT * FROM test_table_2; col1 | col2 ------+------ 1 | A 2 | B 3 | C (3 行) /* 左右同じ結果が返る。 */ testdb=# SELECT * FROM test_table_2; col1 | col2 ------+------ 1 | A 2 | B 3 | C (3 行) /* 右のコミット前のアップデートは左に反映されない。 */ testdb=# UPDATE test_table_2 SET col2='F' WHERE col1= 1; /* 右のトランザクション待ちとなる */ ERROR: could not serialize access due to concurrent update /* 強制的にROLLBACKされる。 */
Transaction 2
※ 先に更新したトランザクションがコミット → 後から更新したトランザクションはキャンセル。
testdb=# BEGIN;
BEGIN
testdb=# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
testdb=# SELECT * FROM test_table_2;
col1 | col2
------+------
1 | A
2 | B
3 | C
(3 行)
testdb=# UPDATE test_table_2 SET col2='D' WHERE col1= 1;
UPDATE 1
testdb=# SELECT * FROM test_table_2;
col1 | col2
------+------
2 | B
3 | C
1 | D
(3 行)
testdb=# COMMIT;
COMMIT
Case2
Transaction 1
testdb=# BEGIN; BEGIN testdb=# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET testdb=# SELECT * FROM test_table_2; col1 | col2 ------+------ 1 | A 2 | B 3 | C (3 行) /* 左右同じ結果が返る。 */ testdb=# SELECT * FROM test_table_2; col1 | col2 ------+------ 1 | A 2 | B 3 | C (3 行) /* 右のコミット前のアップデートは左に反映されない。 */ testdb=# UPDATE test_table_2 SET col2='F' WHERE col1= 1; /* 右のトランザクション待ちとなる */ UPDATE1 /* UPDATE成功 */ testdb=# COMMIT; COMMIT
Transaction 2
※ 先に更新したトランザクションがロールバック → 後から更新したトランザクションが反映される。
testdb=# BEGIN;
BEGIN
testdb=# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
testdb=# SELECT * FROM test_table_2;
col1 | col2
------+------
1 | A
2 | B
3 | C
(3 行)
testdb=# UPDATE test_table_2 SET col2='D' WHERE col1= 1;
UPDATE 1
testdb=# SELECT * FROM test_table_2;
col1 | col2
------+------
2 | B
3 | C
1 | D
(3 行)
testdb=# ROLLBACK;
ROLLBACK