この記事の目的は、select文を使用してOracleデータベースのレコードをロックする方法を説明することです。
はじめに
この記事の目的は、select文を使用してOracleデータベースのレコードをロックする方法を説明することです。 これにより、レコードを変更することなくレコードをロックすることができます。
これはあまり一般的なユースケースには見えないかもしれませんが、真実は、特定のレジスタを更新することを決定する前にいくつかの複雑な検証を行う必要があり、それらの検証中にロックされた状態を維持する必要があるため、他のトランザクションが同時にそれを変更することはできない、より複雑なプログラム(例えばPL/SQLで実装されている)に必要な場合があるということです。
このチュートリアルでは、SQL Developerを使用してデータベースと対話し、クエリを実行します。
同じレコードをロックする
いつものように、データを保持するための単純なダミーテーブルを作成することから始めます。 以下の作成例を確認してください。
create table Worker(WorkerID varchar(20),WorkerName varchar(255),WorkerJob varchar(255),CONSTRAINT PK_Worker PRIMARY KEY (WorkerID));
その後、いくつかのダミーレコードを挿入するので、作業するデータがあります。 3つのレコードを挿入し、トランザクションをコミットします。 SQL Developerメニューのcommitボタンを使用するか、SQL文を使用してトランザクションを明示的にコミットできます。
insert into worker values ('1','John', 'nurse');insert into worker values ('2','Grace', 'farmer');insert into worker values ('3','Smith', 'doctor');
今度は、独立したトランザクションでSQLステートメントをテストするために、新しい共有されていないワークシートを開きます。 その方法については、図1を確認してください。 SQL Developerの共有されていないワークシートの詳細については、前回の記事を参照してください。
図1–新しい非共有ワークシートを開きます。
さて、最初に行うことは、両方のワークシートで通常のselectを実行することです。 私たちは、WorkerIDが1に等しいレコードを取得するためにselectを行います。 両方のワークシートで同じクエリを実行するだけです。
select * from worker where WorkerID = 1;
予想通り、並行性に問題はなく、両方のトランザクションでレコードを受け取ります(WorkerNameは”John”に等しい)。
ここで、最初のワークシート(テーブルを作成した場所と同じ)に戻り、selectステートメントの最後に”for update”句を追加します。 繰り返しますが、コミットやロールバックはしないでください。
select * from worker where WorkerID = 1 for update;
これを行うと、結果セットのレコードを更新する必要なくロックしています。 つまり、レコードを明示的にロックしています。 もちろん、一度ロックしたら、必要に応じて更新することができます。 レコードのロックは、次のコミットまたはロールバックを実行するときに解放されます。
だから、ロックが動作しているかどうかをテストするために、我々は今、第二のワークシート(私たちが開いた共有されていないワークシート)に行きます。 そこで、通常のselectを実行すると、「for update文」なしで問題なくレコードが取得されます。
select * from worker where WorkerID = 1;
しかし、selectを繰り返すと、最後に”for update”文が表示され、他のトランザクションにはWorkerIDが1に等しいレコードがロックされているため、再度ロックしようと
select * from worker where WorkerID = 1 for update;
ロックを解除するには、最初のワークシートに戻り、トランザクションをコミットまたはロールバックします。 次に、共有されていないワークシートに戻ると、SQLステートメントが実行され、目的のレコードが返されます。
異なるレコードのロック
注意すべき重要なことは、結果セットの一部であるレコードのみがトランザクションによってロックされることです。 したがって、異なるトランザクションは、異なるレコードで”更新の選択”を行うことができます。
これをテストするには、最初のワークシートに移動し、次のselect文でレコード1と3の両方を選択します:
select * from worker where WorkerID = 1 or WorkerID = 3 for update;
次に、共有されていないワークシートに移動し、レコード2をロックしてみてください。
select * from worker where WorkerID = 2 for update;
WorkerIDが2に等しいレコードは最初のトランザクションによってロックされていないため、動作して結果を返す必要があります。 ここで、同じ共有されていないワークシートで、Worker IDが1のレコードまたはWorker IDが3(またはその両方)のレコードをロックしようとすると、最初のワークシートからトラ
関連コンテンツ
- Oracle Select for update statment