##はじめに
更新対象のテーブルまたは行に対してロックをする方法を試したのでメモ。
##テーブルロック
指定したテーブル全体をロックします。
MODEによってロックする範囲が変わります。
LOCK TABLE テーブル名
IN ロックのMODE
MODE [ WAIT [ 待機時間 ] | NOWAIT ]
ロックのMODEはいくつか種類があり、以下いずれかを指定します。
・ROCK SHARE
・SHARE UPDATE
ロックされたテーブルへの同時アクセスは可能。
排他アクセスのためテーブル全体をロックはできません。
・ROW EXCLUSIVE
挿入(INSERR)、更新(UPDATE)、削除(DELETE)の実行時に自動でロックされます。
・SHARE
ロックされたテーブルへの同時アクセスは可能。
ロックされたテーブルへの更新はできません。
・SHARE ROW EXCLUSIVE
ロックされたテーブルの行を見ることは可能。
SHAREでロックはできません。
ロックされたテーブルへの更新はできません。
・EXCLUSIVE
ロックされたテーブルへの同時アクセスは可能。
他挿入(INSERR)、更新(UPDATE)、削除(DELETE)はできません。
※正直、EXCLUSIVEしか使用したことがないので間違いがあるかもしれません…
確認後修正します。
MODEに記載するWAITとNOWAITとはロックをしたテーブルに対して更新や削除を行ったときに
・WAIT:ロックが取得できるまで何秒待機するか指定できます。
・NOWAIT:即時にエラーメッセージを表示します。
という違いがあります。
WAITもNOWAITどちらも記載しなかった場合には無限に待機します。
##使用例
Sample_T テーブルに対してロックを取得します。
この場合、他機能等からロックをしようとするとエラーが発生します。
すでにロックがされているテーブルに対してロックをしようとします。
LOCK TABLE Sample_T
IN EXCLUSIVE
MODE NOWAIT
すると以下のようなエラーが返されます。
ORA-00054: リソース・ビジー。NOWAITが指定されているか、タイムアウトしました
##テーブル行ロック
先ほどのテーブル全体をロックするのではなく、指定した行のみをロックします。
テーブルデータが数件しかない場合はテーブルロックでもよいかもしれませんが
データ件数が何百万ある場合や複数の人が対象のテーブルを操作する場合にはロックする行を指定する方がよいかも入れません。
SELECT 列名
FROM テーブル名
WHERE 条件
FOR UPDATE
[OF テーブル名.列名]
[ WAIT [ 待機時間 ] | NOWAIT ]
OFはテーブルを結合する場合に利用します。
今回は利用しなかったため、割愛します…。
WAIT、NOWAITは先ほどのテーブルロックと同じ意味となります。
NOWAITで発生するエラー内容も同様です。
PL/SQLの場合、SELECT文にはINTOが必要となります。
INTO句がないと以下のエラーが発生します。
PLS-00428: INTO句はこのSELECT文に入ります。
入ります。というよりは要りますよ、という意味だと思います。
そのためPL/SQLでこの行ロックを行う場合はSELECTで問い合わせた結果を変数に代入する必要があります。
また、変数だと問い合わせ結果が複数あった場合、0件だった場合にエラーとなります。
注意です。
##おわり
今回、行のロックの条件ではまったのでまた別記事でまとめようと思います。
ひとつの問題にはまったときにそもそも何がしたいのかという着眼点がずれるとはまりますねー。
最後まで見てくださりありがとうございました。