2007年7月18日水曜日

Oracleでロック

スズキです。

Kuina-Dao使うようになって、SQLがしがし書くようになって、
Oracleも使ってるので、初心にもどって、ロックに関して勉強しなおしました。

まずは別セッションで同一行に対してアップデートしたらどうなるかです。

[セッション1]
UPDATE HOGE
SET HOGE_STOCK = 10
WHERE = HOGE_ID = 1

[セッション2]
UPDATE HOGE
SET HOGE_STOCK = 5
WHERE = HOGE_ID = 1

最初にセッション1のUPDATE文を実行して、
次に、セッション2のUPDATE文を実行すると、
セッション1をコミット/ロールバックするまで、
セッション2のアップデート文のレスポンスは返ってきません。(WAIT中)

次は"FOR UPDATE"と"NOWAIT"です。
下記のよにSELECT文の最後に"FOR UPDATE"をつけると、

SELECT *
FROM HOGE
WHERE HOGE_ID = 1
FOR UPDATE

コミット/ロールバックするまで対象行にロックがかかります。
ロックがかかっているときの振る舞いは上記UPDATE文の場合と同様です。

ただし、"FOR UPDATE"の後にNOWAITをつけると、振る舞いが変わります。
別のセッションが"FOR UPDATE"された行を更新しようとすると、
待ち(WAIT)が発生するのではなく、エラーが返されます。

このように、ロック関係の実験をしていると、
失敗ロックがたまってしまう場合があるので、
そのようなロックを強制解除する必要もあるでしょう。
(やり方は下記参照)
http://kamoland.com/oracle/lockfree.html

ORマッピング使ってたときは、
SQL直接いじれなかった(いじりたくなかった)ので、
このあたりは、あまり気にしないようにしてたなー。
(案件的に気にする必要なかったし)

--
blog: http://suz-lab.blogspot.com/

0 コメント: