これらは、同じcontent_idで挿入されている2つのコメントです。コメントを挿入するだけで、コンテンツ行のSHAREロックが解除され、最初のトランザクションが完了するまでその行を削除する別のトランザクションを停止します。
ただし、トリガーは次にロックをEXCLUSIVEにアップグレードし、これは同じプロセスを実行する同時トランザクションによってブロックされる可能性があります。次の一連のイベントについて考えてみます。
Txn 2754 Txn 2053
Insert Comment
Insert Comment
Lock Content#935967 SHARE
(performed by fkey)
Lock Content#935967 SHARE
(performed by fkey)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2053's share lock)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2754's share lock)
デッドロック。
1つの解決策は、すぐにすることです。 前のコンテンツ行を排他的にロックします コメントを挿入します。つまり
SELECT 1 FROM content WHERE content.id = 935967 FOR UPDATE
INSERT INTO comment(.....)
別の解決策は、パフォーマンスに必要であると証明できる場合を除いて、この「キャッシュカウント」パターンを完全に回避することです。その場合は、キャッシュされたカウントをコンテンツテーブル以外の場所に保持することを検討してください。カウンター専用のテーブル。これにより、コメントが追加されるたびにコンテンツテーブルへの更新トラフィックも削減されます。または、カウントを再度選択して、アプリケーションでmemcachedを使用することもできます。このキャッシュされたカウントを保存する場所がチョークポイントになるという事実を回避することはできません。安全に更新する必要があります。