- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2021-06-17T13:14:55+09:00","default:ryuichi","ryuichi")
#author("2021-06-17T13:54:02+09:00","default:ryuichi","ryuichi")
* 行ロック - FOR UPDATE [#o09f5d72]
Session A | Session B
========================================================================================================
=> BEGIN; SELECT * FROM t1 WHERE id = 1 FOR UPDATE; |
BEGIN |
id | n |
----+----- |
1 | 200 |
(1 row) |
|
# (1) ↑のSELECTの結果はすぐに表示される |
| => BEGIN; SELECT * FROM t1 WHERE id = 1 FOR UPDATE;
| BEGIN
|
| # (2) ↑のSELECTはブロックされ、すぐには表示されない
|
# (3) ↓のUPDATEがCOMMITされると、 |
|
=*> UPDATE t1 SET n = 100 WHERE id = 1; |
UPDATE 1 |
=*> COMMIT; |
COMMIT |
|
| # (4) 左のAのCOMMITが終わると、ブロックが解除されて
| # SELECTの結果が↓のように表示される
=> |
| id | n
| ----+-----
| 1 | 100
| (1 row)
|
| =*>
|
** FOR UPDATE [#i82e08c7]
Session A | Session B |
========================================================================================================================================
=> BEGIN; SELECT * FROM t1 WHERE id = 1 FOR UPDATE; | | 1. AのSELECTの結果はすぐに表示
| | される
id | n | |
----+----- | |
1 | 200 | |
| => BEGIN; SELECT * FROM t1 WHERE id = 1 FOR UPDA | 2. BのSELECTはブロックされ、すぐ
| TE; | には表示されない
| |
=*> UPDATE t1 SET n = 100 WHERE id = 1; | | 3. AのUPDATEがCOMMITされると、
=*> COMMIT; | |
| id | n | 4. ブロックが解除されて
| ----+----- | BのSELECTの結果が表示される
| 1 | 100 |
** FOR UPDATE NOWAIT [#e0fede94]
Session A | Session B |
==========================================================================================================================================
=> BEGIN; SELECT * FROM t1 WHERE id = 1 FOR UPDATE NOWAIT;| | 1. NOWAITでSELECTすると、
id | n | |
----+----- | |
1 | 100 | |
| |
| |
| => BEGIN; SELECT * FROM t1 WHERE id = 1 FOR UPDAT | 2. BのSELECTはブロックされずに
| E NOWAIT; | 即時に失敗する
| |
| ERROR: could not obtain lock on row in relation |
| "t1" |
=*> UPDATE t1 SET n = 200 WHERE id = 1; | |
=*> COMMIT; | |
| =!> ROLLBACK; | 3. BでROLLBACKすると、
| => SELECT * FROM t1 WHERE id = 1; | AのUPDATEの結果は反映され
| id | n | ている
| ----+----- |
| 1 | 200 |
| |
** FOR UPDATE SKIP LOCKED [#u637a2c3]
Session A | Session B |
======================================================================================================
=> BEGIN; SELECT * FROM t1 WHER | => | 1. SKIP LOCKEDでSELECTすると、
E id = 1 FOR UPDATE SKIP LOCKED | => |
; | => |
id | n | => |
----+----- | => |
1 | 200 | => |
| => |
=*> | => BEGIN; SELECT * FROM t1 WHER | 2. BのSELECTはAでロックされた行を
=*> | E id = 1 OR id = 2 FOR UPDATE S | SKIPして結果が表示される
=*> | KIP LOCKED; |
=*> | id | n |
=*> | ----+----- |
=*> | 2 | 100 |
=*> | |
=*> UPDATE t1 SET n = 200 WHERE | =*> | 3. AでUPDATE、COMMITすると、
id = 1; | =*> |
=*> COMMIT; | =*> |
=> | =*> SELECT * FROM t1; | 4. ロックが解除されて、BのSELECTに
| id | n | 結果として表示される
| ----+----- |
| 2 | 100 |
| 3 | 100 |
| 1 | 200 |
| |