0

簡単な背景ストーリー:

最近、データベースのロックに問題がある非常に古いアプリケーションに取り組んでいます。アプリは Java で作成され、Hibernate を使用します。私たちが特定した問題の 1 つは、READ_COMMITED と READ_UNCOMMITED の間で分離レベルが頻繁に変更される一方で、トランザクションが不自然に長く存続することです。トランザクションが小さくなるようにコードをリファクタリングすることが明確な解決策であることは認識していますが、これは膨大な作業であり、現時点では余裕がありません (アプリのほとんどの使用部分は新しいシステムに移行されていますが、この手順は比較的時間がかかります)。 )。

そのため、すべての Select 操作に READ_UNCOMMITED を使用し、その他すべてに READ_COMMITED を使用しているため、私たちを支援してきた DBA は、分離レベルをグローバル READ_COMMITED に変更し、すべての選択クエリを変更してヒント 'with( NOLOCK)」。彼は、トランザクション内で分離レベルを頻繁に変更する必要がないという利点を提供しながら、機能的にはデータの取得方法に違いはないはずだと言います (現在は問題なくダーティ リードを使用しているため)。彼の考えは、分離レベルの変更が原因でデータベースがロックされるという最近の報告にも関連していると思います。

それで - マップされた Java オブジェクトと HQL の使用によって自動的に生成されるすべてのクエリに 'with (nolock)' ヒントを追加するように hibernate に指示できますか?これはそれを押しているように見えますが:))分離レベルを変更せずに?

最後の補足: 私たちは古いバージョンの hibernate v3.5 を使用しており、今のところアップグレードの可能性は低いです。何人かの信じられないほど「賢い」人々が、アプリケーションが使用する独自のコードを挿入して、ある時点でそれを汚染することにしました。アップグレードを何度も試みましたが、失敗しました。

また、かなりの数の関連スレッドをチェックしましたが、一般的な考え方は、nolock を使用しないで、分離レベルを変更することです。

Edit1: アプリは過去 12 年間継続的に開発されてきたため、現在の開発チームが一度も見たことのないモジュールがたくさんあります。理想的なソリューションは、すべての識別を必要としないものです。永続化されたオブジェクトを使用する Java コードの 1 ビット。

Edit2:これについて考えられる方法-Hibernateが許可する場合-dbドライバーに渡される前に、フォーマットされたSQLクエリを受け取る形式のInterceptorを追加することです。次に、何らかの形式の正規表現を使用して、ヒントを自分で追加します。

事前にどうもありがとうございました。

4

1 に答える 1

0

(NOLOCK) は HQL では使用できません。ただし、クエリを変更する場合は、ネイティブ SQL を使用できます。何かのようなもの:

getCurrentSession().createSQLQuery("select * from table with(NOLOCK)").list();
于 2016-05-03T18:29:26.840 に答える