0LINEはじめにトランザクション管理機能の1つである排他制御機能についてまとめました。共有ロック、占有ロックの違い、またデッドロックとその回避策について図解でまとめています。個々のトランザクションが他のトランザクションに影響を与え、タイミングによっては誤った結果になってしまいます。並列実行されているトランザクションを直列実行可能(直列実行可能性)になるように制御しています。この時に行っている制御が排他制御です。保証されているといいます。占有ロックと共有ロックの違いとは排他制御は主に、データベースのロックによって実現しています。ロックとは更新や参照する対象データに鍵をかけて他のトランザクションからアクセスできないようにすることです。ロックには占有ロックと共有ロックの2種類があります。共有ロックと占有ロックの違い一般的にトランザクションがデータを参照する前に共有ロックを実施します。一般的にトランザクションがデータを更新する前に占有ロックを実施します。他のトランザクションからは該当データに対して共有ロックはかけれるが、占有ロックはかけれません。共有ロック中に、他のトランザクションから該当データの参照はできますが、更新はできません。他のトランザクションからは該当データに対して共有ロック、占有ロック共にかけれない。占有ロック中に、他のトランザクションから該当データの参照、更新はともにできません。ロック対象となるデータの単位をロックの粒度と言います。ロックの粒度が行の場合トランザクションは同時に同じテーブルを参照、更新することは可能です。ロックの粒度がテーブルの場合には同じテーブルにアクセスするにはロックが解除されるまで待つ必要があります。処理が続行できなくなった状態のことをデッドロックと言います。商品名変更トランザクションは商品テーブルのロックがそれぞれ成功しています。商品名変更トランザクションはすでに(在庫変更トランザクションに)ロックされている在庫テーブルのロックが解放されるのをお互い待つことになります。このような状態がデッドロックです。DBMSが一定時間ロック待ちになっているトランザクションを検出してタイムアウトエラーで落としてくれます。待ちグラフというものを利用してデッドロックを検出することもできます。各トランザクションの資源ロックの順番を同じにすれば良いです。待ちが発生してもトランザクション完了によってロックが解放されるのでデッドロックを避けることができます。あとは、、、ロックの粒度を必要以上に大きくしないことです。意図せずインデックスが効いておらず、実はテーブルロックになってデッドロックが発生するという恐ろしいことが実際の現場で見たことがあります)まとめ今回はトランザクション管理機能の排他制御について確認しました。利用しているDBMSのロックの粒度は行ロックなのか?テーブルロックなのか?(意図した通り本当に行ロックになってますか??)を調べてみたり、ロック解放待ちの上限時間は何秒に設定しているのかなどは押さえておきましょう。最後に、デッドロックではないですが、、、DBMSにデッドロックとみなされてエラーとなってしまったケースを体験したことがあるので紹介します。別のユーザが一括更新の処理対象のうちの1つのデータを更新しようとしてロック待ちとなり、ロック解放待ち上限時間を超えてDBMSからエラーが返される。(DBMSは行ロック)ということを実際に体験しました。これが発生するたびに毎回アラートが上がって・・・って感じでした。現場で必要なデータベース関連のまとめ記事を作ったので是非そちらもご覧ください。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。