- ベストアンサー
更新ロックとデッドロックについての質問
- ロックの種類について質問します。共有ロック、排他ロック、更新ロックの違いがよくわかりません。
- 更新ロックは、更新を前提にして共有ロックをかけることで、更新前に排他ロックに切り替わります。
- データを更新するためには排他ロックをかけなければならないことはわかりますが、なぜその前に共有ロックをかけるのでしょうか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
sqlcmdのプロンプトを二つ立ち上げて (トランザクション1) begin tran go select * from テーブル with ( updlock ) where 条件 go (トランザクション2) update テーブル set 項目 = ~ where 条件 go として見てください。トランザクション2は待ちになります。 トランザクション1のselect文の with ( updlock ) を取ると待ちになりません。
その他の回答 (3)
- nora1962
- ベストアンサー率60% (431/717)
更新ロックはSELECTで WITH ( UPDLOCK ) を指定した時の場合ですね。 一方、排他ロックはINSERT,UPDATE,DELETEを直接実行した場合発生します。 ですので、SELECTで値を取得して、その値に応じて処理を分岐したいなどの場合に使われます。
お礼
回答ありがとうございます。 少し明かりが見えてきた気がします。 ・INSERT,UPDATE,DELETEをいきなり実行すると排他ロックになる。 (特にSQL文に指定はしない?) ・INSERT,UPDATE,DELETEの前にSELECTで WITH ( UPDLOCK ) を指定すると更新ロックになり、その後のINSERT,UPDATE,DELETEの実行で排他ロックになる。 という理解で間違っていないでしょうか。 ある程度デッドロックを防げるのかどうかも教えてくださるとうれしいです。 SELECTで WITH ( UPDLOCK )を実行して更新する範囲を宣言、そこでエラーになるなら待ちの状態になるのかな、と想像しています。
- equinox2
- ベストアンサー率48% (321/660)
以下をご参照ください。 http://www.atmarkit.co.jp/fdotnet/entwebapp/entwebapp09/entwebapp09_01.html 更新ロックと排他ロックの違いは、その期間中に共有ロック(読み込み)を 許すかどうかです。 #どちらを使うべきかは、何を優先すべきかで違う・・
お礼
回答ありがとうございます。 そのページは何度も読んだのですが、完全には理解できないでいます。 あるレコードを読もうとしたら他のトランザクションが排他ロックをかけていたとします。 自分も排他ロックならエラーになり、更新ロックなら共有ロック待ちとなるのだ(そのおかげでデッドロックがある程度回避できるのかな)と考えているのですが、間違っていますか。
- yorozu_ya
- ベストアンサー率54% (76/140)
> 上のサイトを読んで「デッドロックを回避するため」といったんは理解したのですが、 > 上司は「更新ロックとデッドロックは関係ない」と言います。 関係ない訳ではなく、それとは別のデッドロック問題があり、 一般にデッドロックというとそちらの問題を指すということです。 (1)AプログラムがXテーブルのX1レコードをロック (2)BプログラムがYテーブルのY1レコードをロック この状態で (3)AプログラムがYテーブルのY1レコードをロックしようとする (4)BプログラムがXテーブルのX1レコードをロックしようとする これが一般に言われるデッドロック問題です。 回避方法は、XとYのどちらを先にロックするのかをシステム内で統一する。
お礼
デッドロックのご説明ありがとうございます。かならずXテーブル→Yテーブルの順でロックすればデッドロックの頻度は減りそうですね。でも同じテーブルの別レコードに対してだと効果はないということでしょうか。 目下知りたいのは排他ロックと更新ロックの違いと使い分けなので、それについてご教示くださればと思います。
お礼
えーと、それはSQLServerでしょうか。今手元に使える環境がないので残念ながら確認できないのすが、トランザクション1がwith ( updlock )つきのSelectを実行すると トランザクション2が待ちになるんですよね。 その状態でトランザクション1にend tranを実行すると、トランザクション1は終了してしまい、トランザクション2は待ちが解除されて実行になると考えていいですか。 あと、更新ロックはデッドロックをある程度防げるのかどうか教えていただけるとうれしいです。もしかして「一概に言えない」ということなのでしょうか。