トランザクション

テキスト

  1. http://www.postgresql.jp/document/current/html/tutorial-transactions.html
  2. http://www.postgresql.jp/document/current/html/sql-begin.html
  3. http://www.postgresql.jp/document/current/html/sql-commit.html
  4. http://www.postgresql.jp/document/current/html/sql-rollback.html

トランザクション

RDBMSは複数の同時アクセスによりデータの不整合が起きないように設計されている。その機能がトランザクションと呼ばれている。


 BEGIN;  トランザクションの開始

COMMIT [WORK];  or  END;  トランザクションの終了

ROLLBACK [WORK]; or  ABORT;  トランザクションの異常終了

test=# CREATE TABLE test1(i int, j int);
CREATE
test=# INSERT INTO test1 VALUES(1, 100);
INSERT 41877 1
test=# SELECT * FROM test1;
 i |  j
---+-----
 1 | 100
(1 row)

test=# BEGIN;
BEGIN
test=# INSERT INTO test1 VALUES(2, 200);
INSERT 41878 1
test=# SELECT * FROM test1;
 i |  j
---+-----
 1 | 100
 2 | 200
(2 rows)

test=# ROLLBACK;
ROLLBACK
test=# SELECT * FROM test1;
 i |  j
---+-----
 1 | 100
(1 row)

test=# BEGIN;
BEGIN
test=# INSERT INTO test1 VALUES(2, 200);
INSERT 41879 1
test=# SELECT * FROM test1;
 i |  j
---+-----
 1 | 100
 2 | 200
(2 rows)

test=# a;
ERROR:  parser: parse error at or near "a"
test=# SELECT * FROM test1;
NOTICE:  current transaction is aborted, queries ignored until end of transactio
n block
*ABORT STATE*
test=# COMMIT;
COMMIT
test=# SELECT * FROM test1;
 i |  j
---+-----
 1 | 100
(1 row)

トランザクションの隔離レベル

リードコミッティド(read committed) <--  ダーティリード 起きない

u1:test=# CREATE TABLE test2 (a int);
u1:CREATE
u1:test=# INSERT INTO test2 VALUES(2);
u1:INSERT 41882 1
u1:test=# BEGIN;
u1:BEGIN
u2:test=# BEGIN;
u2:BEGIN
u1:test=# SELECT * FROM test2;
u1:a
u1:---
u1:2
u1:(1 row)
u2:test=# UPDATE test2 SET a = 20;
u2:UPDATE 1
u2:test=# SELECT * FROM test2;
u2:a
u2:----
u2:20
u2:(1 row)
u1:test=# SELECT * FROM test2;
u1:a
u1:---
u1:2
u1:(1 row)
u2test=# COMMIT;
u2:COMMIT
u1:test=# SELECT * FROM test2;
u1:a
u1:----
u1:20
u1:(1 row)
u1:test=# COMMIT;
u1:COMMIT

Non-repeatable Read

u1:test=# BEGIN;
u1:test=# SELECT * FROM test2;
u1:a
u1:---
u1:2
u1:4
u1:6
u1:(3 rows)
u2:test=# BEGIN;
u2:test=# UPDATE test2 SET a = a + 1;
u2;UPDATE 3
u2;test=# SELECT * FROM test2;
u2:a
u2:---
u2:3
u2:5
u2:7
u2:(3 rows)
u2:test=# COMMIT;
u1;test=# SELECT avg(a) FROM test2;
u1:avg
u1:---
u1:5
u1(1 row)

シリアライザブル(serializable)

u1:test=# BEGIN;
u1:test=#  SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
u1:SET VARIABLE
u1:test=# SELECT * FROM test2;
u1:a
u1:---
u1:2
u1:4
u1:6
u1:(3 rows)
u2:test=# BEGIN;
u2:test=# UPDATE test2 SET a = a + 1;
u2;UPDATE 3
u2;test=# SELECT * FROM test2;
u2:a
u2:---
u2:3
u2:5
u2:7
u2:(3 rows)
u2:test=# COMMIT;
u1;test=# SELECT avg(a) FROM test2;
u1:avg
u1:---
u1:4
u1(1 row)

MVCC(Multi Version Concurrency Control) <-> ロック(lock)

トランザクションの同時実行制御