Hibernate 3.6.1.FINAL
に対して使用してOracle 11g
います。
データベースでブロッキングロックが発生しています。これは、Hibernateの予期しない副作用が原因であると考えられます。
これは、解決する必要のある重要な問題です。データベースのブロックがすぐにロックされ、トランザクションがタイムアウトになり、本番環境が停止するためです。
Hibernateが子のコレクションの舞台裏での削除と再挿入を実行できる特定のシナリオがあるかどうか、または削除/挿入でブロックロックを引き起こす可能性がある方法があるかどうかを調べようとしています。
考えられる原因についてのアイデア/提案/洞察を探していますが、必ずしも正確な答えではありません。
関係するエンティティとそのマッピングを分離しました。残念ながら、大量のコードを含む巨大なレガシーシステムがあるため、簡単な例を考え出す必要がありました。
Parent.hbm.xml
// Parent has a unique ID generated with a Sequence,
// an index column called ORD, and a Version column called UPDATE_COUNTER.
<!-- bi-directional one-to-many association to Child -->
<bag
name="children"
lazy="false"
inverse="true"
cascade="all-delete-orphan"
order-by="ord asc">
<key column="PARENT_ID" />
<one-to-many class="Child" />
</bag>
Child.hbm.xml
// Child has a unique ID generated with a Sequence,
// and a Version column called UPDATE_COUNTER.
<!-- bi-directional many-to-one association to Parent -->
<many-to-one
name="parent"
class="Parent"
not-null="true"
>
<column name="PARENT_ID" />
</many-to-one>
私たちのDBAは、次のことを確認していると報告しています。
ブロックされたSQL:
insert into CHILD (UPDATE_COUNTER, ORD, PARENT_ID, ID) values (:1 , :2 , :3 , :4)
ブロッキングSQL:
delete from CHILD where ID=:1 and UPDATE_COUNTER=:2
これが私がこれまでに試したことです:
コードベースの完全な監査を行い、同じ主キーを持つ行を削除および挿入する場所がないことを確認しました。子のINSERTはすべて、IDをnullに設定して実行されます。この場合、シーケンスは一意のIDを生成します。
show_sqlをオンにしました。また、DBAは、開発中にバインド変数を取得できるように、すべてのDMLアクティビティをキャプチャするトリガーをChildに設定しました。
Hibernateはすべてを削除してから、バッグとリストに再挿入できるという次の記事を見つけました。
しかし、私はこれが起こっていないと判断しました。真ん中の子オブジェクトの1つを削除するテストコードを作成し(ORD = 5、ORD=0からORD=9の10個の子のコレクション)、Parentを保存しました。
DMLアクティビティテーブルで、削除された子に対して削除が発行され、ORDを正しい値に設定した残りの9人の子に対してUPDATEが実行されたことがわかりました。
私が言ったように、私は正確な答えを探していません。Hibernateの経験が豊富な人が、私が実行できる追加のパスや方法について洞察や提案を提供してくれれば、私は非常に感謝しています。
事前にどうもありがとうございました。