3

永続層にはhiberante、c3p0、postgresqlを使用しています。データ集約型のジョブ(主に選択/挿入)を実行しているときに、開発者の1人がコミットする前にentityManager.flush()を使用することにしました。

entityManager.getTransaction().begin()
insert n elements
entityManager.flush()
entityManager.getTransaction().commit()

しばらくすると、データ集約型のジョブを実行しているすべてのスレッドがブロックされたように見え、プールからのデータベース接続を待機していることがわかりました。「Idleintransaction」状態にあるプール上のすべての接続。状況は毎回繰り返される可能性があります。

flush()を削除した後、状況は消えました。

なぜこれが起こるのか誰かが知っていますか?

ありがとう

4

1 に答える 1

4

hibernate には、実行する sql コマンドのリストを単純に収集し、コミット時にそれらを実行するインテリジェントなキャッシュ システムがあります。Flush は、こ​​れらのコマンドを部分的に実行する役割を果たします。これは役立つように思われるかもしれませんが、hibernate がフラッシュなしでコミットするまで何もしないことを考えると、データベースは一度にではなく短いバーストで大きなトランザクションを処理しなければならなくなります。

これは、同僚に一度に複数の紙を細断させるのではなく、細断するために 1 枚の紙を同僚に渡すことと同じです。これを、データベースがトランザクションの途中でレコードをロックする可能性があるという事実と組み合わせると、最初にフラッシュを呼び出した瞬間から、データベースはコミットするまでコマンドを実行するタスクに専念します。データベースが待機しておらず、一度にすべてのコマンドを実行している場合、実際の作業を行うのにかかる時間内にデータベースが終了する可能性があります。

要するに、休止状態は自分が何をしているかを知っています。フラッシュは休止状態の通常の機能をオーバーライドし、注意しないと実際にパフォーマンスを低下させる可能性があります。順序が重要な場合 (挿入前に削除を実行するなど) にのみ、おそらくフラッシュを使用する必要があります。

于 2012-09-12T10:05:57.497 に答える