私はHibernateの上にSpringを使用するプロジェクトを持っている。 HSQLDBは、JUnit単体テストのデータベースとして機能します。非常に頻繁に(時間の50%)、私たちのビルドは特定のエンドポイントにヒットした後にハングします。Spring、Hibernate、HSQLDB:メインスレッド終了時にJUnitテストケースがハングアップするが、2番目の非同期スレッドが処理中
テストされているエンドポイントの1つが、非同期スレッドを起動して終了前にクリーンアップ作業を行うものです。メインスレッドの結果に依存するため、エンドポイントの先頭からは起動できません。その後
@Transactional
public fooObj findCustomerFoo(Customer cust) {
CustFooCollection custFooCollection = otherService.getCustomerFoo(cust);
cleanupFooService.cleanupFoo(custFooCollection.getBadFoo());
return custFooCollection.getGoodFoo(); //return to the webservice layer that
///populates the response object and kicks it out
}
CleanupFooServiceにあなたはcleanupFooメソッドを持って次のコードを考えてみ
@Async
@Transactional
public void cleanupFoo(List<Foo> foo) {
//1) Pulls foo from DB
//2) Runs state change and business logic on foo
//3) Saves objects back in DB
}
コードのアイデアはfindCustomerFooはすべて私のfooオブジェクトを引っ張るために必要なすべてのコードをオフに発射するということです。この間にいくつかのフィルタリングが行われ、foosは2つの異なるカテゴリにフィルタリングされます。良いフォームは呼び出し元に戻り、状態の変更とリポジトリでの更新が必要な悪いfoosです。
パフォーマンス上の理由から、ロジックのビットがあり、そこにダブルチェックインしているので、要求と同時にクリーンアップを実行したくありませんでした。それは安全に裏で起こることがあります。
最近、私たちのビルドマシンにいくつかの変更が加えられ、ユニットテストで問題が発生しました。非常に頻繁にこのエンドポイントがテストの一部としてヒットすると、メインスレッド(findCustomerFooを実行する)は2番目のスレッド(cleanupFoo)が終了する前に終了します。それが起こると、ビルドがハングアップします。ログでは、cleanupFooがデータベースを呼び出し始めましたが、まだ戻っていないことがわかります。私は、クエリが飛行中で、データベースが応答するのを待っているかどうか、またはハイバーネイトが依然としてクエリをプリペアしている場合、またはハイバーネイトがまだ結果を処理しているかどうかはわかりません。私はスレッドが現在データベースに行くのを処理するリポジトリメソッドにあることを知っています。
正常なビルドでは、メインスレッドが非同期スレッドの後に終了することがわかります。これは、Webサービス層の最後のログが原因です。懸垂テストでは、このログは非同期スレッドに存在するログの前に発生します。
このコードは、しゃっくりをしないで生産中にしばらく実行されています。
主なスレッドが終了すると、JUnit/SpringがHSQLDBを停止して2番目のスレッドがハングしてしまうという理論があります。コードを実行しているスレッドが引き続き表示されるため、次の単体テストまたはクラスの実行を開始できません。
これらのハングを停止するにはどうすればよいですか?元のテストケースの作成者は、メモリ内のデータベースを@前にテストされたテストクラスで初期化し、.sqlファイルに存在するデータをシードしました。私はこれらをXML構成内に記述されたデータソースを指すように修正し、ScriptUtilsを使用してシードデータファイルを実行しました。ここでの私の理論は、春に100%制御されているデータソースのセットアップと解凍があった場合、終了する前にスレッドの存在を認識するかもしれないということでした。しかし、これを行い、データソースをシャットダウンしたアフターテストメソッドを削除しても機能しませんでした。