#author("2021-06-17T15:13:39+09:00","default:ryuichi","ryuichi")
#author("2021-06-17T15:14:35+09:00","default:ryuichi","ryuichi")
* 外部キーなカラムに対するFOR UPDATE [#h9cd667c]
** 前提 [#dd6dfed9]
=> SELECT * FROM t1;
t1_id | n | t2_id
-------+----+-------
1 | 10 | 1
2 | 20 | 2
=> SELECT * FROM t2;
t2_id | n
-------+-----
1 | 100
2 | 200
- t1テーブルのt2_idカラムは外部キー制約が設定されている
** SQL [#p7021ee9]
Session A | Session B |
=======================================================================================================
=> BEGIN; SELECT * FROM t1 WHER | => | 1. Aでt2_id=1なカラムがロックすると
E t1_id = 1 FOR UPDATE; | => | t1テーブルだけでなく、
t1_id | n | t2_id | => | t2テーブルも影響を受ける
-------+----+------- | => |
1 | 10 | 1 | => |
| => |
=*> | => UPDATE t2 SET n = 1 WHERE t2 | 2. Bでt2テーブルのnカラムをUPDATEす
=*> | _id = 1; | るのはブロックされず即実行される
=*> | => |
=*> | => UPDATE t2 SET t2_id = 10 WHE | 3. しかし、Bでt2テーブルのt2_idを
=*> | RE t2_id = 1; | UPDATEしようとすると
=*> | | ブロックされる
=*> | |
=*> COMMIT; | | 4. AでCOMMITすると、
| ERROR: update or delete on tab | BでブロックされいたUPDATEが実行
| ERROR: update or delete on tab | BでブロックされていたUPDATEが実行
=> | le "t2" violates foreign key co | される
=> | nstraint "t1_t2_id_fkey" on tab |
| le "t1" |
| DETAIL: Key (t2_id)=(1) is sti |
| ll referenced from table "t1". |
| |
| => SELECT * FROM t2; |
| t2_id | n |
| -------+----- |
| 2 | 200 |
| 1 | 1 |
| |