4

Oracle 11.2g にデッドロックの問題があります。デッドロックが発生する潜在的な理由の 1 つは、子テーブル ロックの親テーブルからの削除です。オラクルのドキュメントから検索しましたが、この種のロックの仕様は見つかりませんでした。ドキュメントの説明や参照は大歓迎です。

これがコードです。

CREATE TABLE table_parent (a NUMBER PRIMARY KEY);
CREATE TABLE table_child (b NUMBER, a NUMBER,PRIMARY KEY (b), CONSTRAINT fk_relation FOREIGN KEY (a) REFERENCES table_parent(a));

INSERT INTO table_parent VALUES (1);
INSERT INTO table_parent VALUES (2);
INSERT INTO table_child VALUES (1,1);
INSERT INTO table_child VALUES (2,1);
INSERT INTO table_child VALUES (3,1);
INSERT INTO table_child VALUES (4,1);

COMMIT;

次に、子テーブルから 1 レコードを削除します。

DELETE FROM table_child WHERE b=4;

コミットを実行する前に V$LOCK テーブルを調べます。「TM」のタイプに「table_child」と「table_parent」という 2 つの新しいロックがあります。

V$LOCK テーブルを検索するクエリは次のとおりです。

SELECT O.OWNER, O.OBJECT_ID, O.OBJECT_NAME, O.OBJECT_TYPE, L.TYPE
FROM DBA_OBJECTS O, V$LOCK L
WHERE O.OBJECT_ID = L.ID1;

問題は、「table_parent」がロックされている理由です。

4

3 に答える 3

3

外部キーの場合のように、「複数の行にまたがる」制約を維持するために、1 つ (つまり DBMS) がトランザクションをシリアル化する必要がある場合があります。シリアライゼーションが必要になるタイミングは、関連するテーブルに対してトランザクションが実行する変更の種類に 1 対 1 で依存します。理論的には (Oracle が行っているスナップショット分離を提供する DBMS で)、変更の種類が複数行の制約に違反する可能性がある場合にのみ、DBMS はトランザクションを自動的にシリアル化する必要があります (たとえば、さまざまなデータを取得することによって)。ロックの種類)。

ここで、外部キーの場合、自問する必要があります: 外部キーはいつ侵害される可能性があるのでしょうか? 4つのシナリオがあります。

  • 親行が削除されます: 子行がまだ存在する場合、FK に違反します。
  • 親行のキーが更新されます: 子行がキーの古い値を「指す」までの場合、FK に違反します。
  • 子行が挿入されます。行が存在しない親行を指している場合、FK に違反します。
  • 子行の fk-column 値が更新されます: 新しい列値が存在しない親行を指している場合、FK に違反します。

関連する (2) テーブルの他のすべてのタイプのトランザクションは、FK に違反することはありません。したがって、あなたの場合、子行が削除され、シリアル化は必要ありません。ただし、Oracleにはおそらく「実装固有の」理由があり、何らかのロックを取得する必要があります。

オラクルがこの種の「不要な」ロックも実行する別のシナリオを見てきました。ここで見つけることができます

トゥーン

于 2013-04-24T06:59:26.297 に答える
1

table_child(a) 列にインデックスを追加します。まさにこの理由で、常に外部キー列にインデックスを付けます。

于 2013-04-24T06:50:47.367 に答える
0

これに対する答えは、ここの例で説明されています http://www.oraclebin.com/2012/12/what-is-deadlock-in-oracle.html

于 2013-12-27T11:02:40.523 に答える