Oracle select for updateのサンプル

SQLのselect for updateのサンプルです。(Oracle)

目次

説明 select for updateとは
サンプル select for updateの挙動の確認
  select for updateにselect for updateをした場合
  ロックされていた場合はエラーにする(select for update nowait)
  ロック状態を確認するSQL

select  for updateとは

select 項目 from テーブル
where 条件
for update;
  • 選択した行に対して、他のトランザクションが更新できないようにします。
    →他のトランザクションは待ちの状態になります。
  • commitまたはrollbackをすることで、他のトランザクションは更新できるようになります。
  • 他のトランザクションは、selectで値を取得することはできます。
  • 以下は、OracleのDML操作での自動ロックのリンクです。
    https://docs.oracle.com/cd/E57425_01/121/SQLRF/ap_locks001.htm

select  for updateの挙動の確認

SQLコマンドラインを2つ立ち上げ、select for updateをした時の挙動の確認します。

1.行のロックを行う

1つめのSQLコマンドラインで、select文にfor updateをつけて実行します。

select * from SYAIN
where ID = '1'
for update;

3行目のfor updateでSYAINテーブルのID=1の行をロックします。

 

2.SQLを実行してみる

2つめのSQLコマンドラインで、select文を実行してみます。

select * from SYAIN
where ID = '1';

1つめのSQLコマンドラインのSQLと同じ条件で実行しています。
結果の取得はできます。

 

3.Updateを実行してみる

2つめのSQLコマンドラインで、update文を実行してみます。

update syain
set name = '竹田'
where ID = '1';

updateを実行した場合、実行されないままの状態になります。待ちの状態です。
以下の図のように反応が返ってきません。

 

.commitを実行してみる

1つめのSQLコマンドラインで、commitを実行すると、

2つめのSQLコマンドラインのupdateの更新も実行されて終了します。

 

select  for updateにselect  for updateをした場合

select for updateでロックを掛けた状態に対して、別のトランザクションでselect for updateした場合は、1つめのselect for updateがcommitかrollbackされるまで2つめのselect for updateは待ちの状態になります。

以下の図のように反応が返ってきません

 

ロックされていた場合はエラーにする(select for update nowait)

select for updateでロックを掛けた状態に対して、別のトランザクションでselect for updateに
no waitをつけて実行した場合は以下のエラーを返します。

「ORA-00054: リソース・ビジー。NOWAITが指定されているか、タイムアウトしました」

以下は、nowaitをつけたときの動きです。

1.1つめのSQLコマンドラインで実行

select * from SYAIN
where ID = '1'
for update;

select文でfor updateをつけています。

2.2つめのSQLコマンドラインで実行

select * from SYAIN
where ID = '1'
for update nowait;

3行目は、nowaitをつけています。

nowaitがあるため、待ちにはならず以下のエラーが発生します。

「リソース・ビジー。NOWAITが指定されているか、タイム・アウトしました。」

 

ロック状態を確認するSQL

ロックは、V$LOCKED_OBJECTテーブルで確認します。

select
OBJECT_ID
,SESSION_ID
,ORACLE_USERNAME
,OS_USER_NAME
,PROCESS
,LOCKED_MODE
from v$locked_object;

ロック状態がある場合はデータが表示されます。
systemユーザで実行しました。権限がないと実行できません。

以下は、OracleのV$LOCKED_OBJECTのリンクです。
https://docs.oracle.com/cd/E57425_01/121/REFRN/GUID-3F9F26AA-197F-4D36-939E-FAF1EFD8C0DD.htm

関連の記事

Oracle SQLコマンドラインを使用するサンプル

△上に戻る