- - PR -
SQLServerでのLOCKについて
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2008-06-19 12:02
LOCKの動作についてお知恵をお貸しください。
実現したいことは以下の通りです。 1.テーブル全体に対して更新不可とするLOCKを行う。 2.レコードの参照は可能(ダーティリードは不可) ロックは行えるのですが、 ロックしたテーブルを他のプロセスから二重にロックしてしまえるようなのです。 @あるプロセスからテーブルロック SET LOCK_TIMEOUT 0 SET TRANSACTION ISOLATION LEVEL READ COMMITTED GO BEGIN TRANSACTION GO select * from M001_USER WITH (TABLOCK, HOLDLOCK); A別のプロセスから同様にロック @↑と同様のSQL実施 B先にロックしたプロセスで一件更新すると 「ロックされています」旨のエラーメッセージ 先にテーブルロックしたプロセス以外からはロックさせず、 かつ、レコードの読み取りを可能にする方法はないのでしょうか? 普通に実現できそうなのですが、失敗してしまっています。 初歩的な問題ですみません。。 |
|
投稿日時: 2008-06-19 12:18
共有ロックになっているからですね。代わりに更新ロックを使用してください。
TABLOCK, UPDLOCK |
|
投稿日時: 2008-06-19 13:29
ありがとうございます。
この場合、共有でも排他でもなく、更新ロックが適切なのですね。 ただ、最初のプロセスでロックすると、 別のプロセスでSELECTで読み取れなくなってしまうのです。 @最初のプロセス SET LOCK_TIMEOUT 0 SET TRANSACTION ISOLATION LEVEL READ COMMITTED GO BEGIN TRANSACTION GO select * from M001_USER WITH (TABLOCK, UPDLOCK); A別プロセスから select * from M001_USER →ロックタイムアウトの旨のエラーメッセージ どうもロックレベルの問題ではないかもしれません。 SQLServerManagementStdioから検証しているのですが、 環境設定の問題でしょうか? どなたかお分りになりませんでしょうか |
|
投稿日時: 2008-06-19 15:36
自己レスです。
SQLServer Management Studioには利用状況モニタがありまして、 ロックの状況が確認できました。 (なにも知らないことが情けない。。) 肝心のロックの状況ですが、 要求モードが'X'(排他モード)になっていました。 WITH(TABLOCK, UPDLOCK)とした場合は、 要求モードが'U'(更新モード)になって欲しい。 なぜだろうか?もう少し調べます。 |
|
投稿日時: 2008-06-19 19:01
自己レスです。
WITH(UPDLOCK)とすることで目的にあったロックがかけられるようです。 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE GO BEGIN TRANSACTION GO select * from M001_USER WITH (UPDLOCK); として状態を確認すると、 PAGEに対して'IU' (おそらく)TABLEに対して'IX' のロックがかかりました。 この状態で別プロセスから操作すると以下のようになりました。 SELECT → OK SELECT WITH(UPDLOCK) → NG UPDATE → NG INSERT → NG テーブルに対してロックをかけたいからTBLLOCKという訳ではないようです。 一括更新ロックを行いたい場合にTBLLOCKを指定する、と以下にありました。 (http://msdn.microsoft.com/ja-jp/library/ms175519.aspx) 一括更新ロック時は、一括読み込みに参加していない他のプロセスは、その間テーブルアクセスできません、とのことでした。 お騒がせ致しましたm(_ _)m |
1