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