デッドロック
- いわゆるデッドロックは、以下で発生しなければならない4つの必要条件です。
- リソースの相互排除条件
- 条件を維持して要求する
- 不可侵の状態
- ループ待機状態
- つまり、アクセスされるリソースは相互に排他的です。つまり、プリエンプティブまたは消費可能なリソースです。
- 複数のトランザクションがすでにリソースを占有していて、他のリソースを取得したい場合、占有されたリソースは不可侵であり、アクセスしたいリソースは循環されて待機されます
- たとえば、次の例
テーブルを作成する
CREATE TABLE `test1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
- id主キーインデックス
クライアント1
--T1时刻
BEGIN;
--行级锁 id=1 的记录
select * from test1 where id=1 for update ;
--T3时刻
--更新 id=2 的记录
update test1 set id=5 where id=2;
クライアント2
--T2时刻
BEGIN;
--行级锁 id=2 的记录
select * from test1 where id=2 for update ;
--T4时刻
--更新 id=1 的记录
update test1 set id=6 where id=1;
- 運転結果
update test1 set id=5 where id=1
> 1213 - Deadlock found when trying to get lock; try restarting transaction
> 时间: 0.002s
分析
端末1は、時刻T1でtest1テーブルのid = 1のレコードに排他ロックを追加します。
端末2は、T2のtest1テーブルのid = 2のレコードに排他ロックを追加します。
端末は、時刻T3にtest1テーブルのid = 2のレコードを更新しようとしています。この時点で、行レコードは排他ロックで追加されており、更新操作を実行できません。ロックを待つ必要があります。リリースされる予定です。
端末2は、時刻T4にtest1テーブルのid = 1のレコードを更新します。この時点で、行レコードは排他ロックで追加されており、更新操作を実行できません。ロックを待機する必要があります。リリースされる予定です。
…
2つのトランザクションは、互いの排他ロックが解放されるのを待つため、デッドロックが発生します