Oracle Database ロックについて

f:id:monozukuri-bu:20191016173821j:plain

みちです。
Oracle Databaseのロックについて勉強していきたいと思います。

ロック

 複数のユーザーが同時に書き込み処理を行うと、矛盾が起きてしまう場合があります。
その矛盾が起こらないようにOracleサーバーでは、書き込み処理に対してロックがかかります。
変更の対象の行ごとに排他ロックをかけてからデータの変更処理が行われ、トランザクションが終了したときに解除されます。 ロックがかかっている行に対して変更処理を行おうとする場合、解除されるまで待機し、そのあとに変更処理が行われます。

実際に試してみましょう。
id、name、num、という列を持った表を作成します。

CREATE TABLE ex1
(
    id NUMBER(2),
    name VARCHAR2(100),        
    num NUMBER(10)
);

INSERT INTO ex1 VALUES (1, 'りんご', 100); 
INSERT INTO ex1 VALUES (2, 'バナナ', 50); 
select * from ex1;
ID NAME NUM
1 りんご 100
2 バナナ 50

ここまでのsqlを打つと結果として上の表のような結果が出ます。

USER Aでデータ確認をします。

SELECT * FROM ex1
WHERE ID = 1;
ID NAME NUM
1 りんご 100

USER Bでデータを確認します。

SELECT * FROM ex1
WHERE ID = 1;
ID NAME NUM
1 りんご 100

USER AがここでID=1の行に排他ロックをかけてデータを更新します。

UPDATE ex1
SET NUM = 25
WHERE ID = 1;

USER BはID=1の行に排他ロックをかけようとしますが、USER AがID=1の行に排他ロックをかけているため、待機状態になります。

UPDATE ex1
SET NUM = 200
WHERE ID = 1;

USER Aでデータを確認します。
NUM列が変更されていますね。

SELECT * FROM ex1
WHERE ID = 1;
ID NAME NUM
1 りんご 25

USER Aでロックを解除します。

COMMIT;

USER Bでデータを確認します。

SELECT * FROM ex1
WHERE ID = 1;
ID NAME NUM
1 りんご 200

USER Aの排他ロックが解除されたため更新処理がされました。

この状態で、USER Aでデータを確認します。
USER Bの変更は確定していないため、USER A側ではUSER Bの変更内容が入っていません。

SELECT * FROM ex1
WHERE ID = 1;
ID NAME NUM
1 りんご 25

USER Bで変更内容を確定し、ロックを解除します。

COMMIT;

USER Aでデータを確認してみると、USER Bが行った変更が反映されていることが確認できます。

SELECT * FROM ex1
WHERE ID = 1;
ID NAME NUM
1 りんご 200

まとめ

 今回はロックついて勉強しました。
身近に使われているシステムの仕組みを知れてよかったです。