永続化コンテキスト(Hibernateのセッション)、EntityManager

複数スレッドで、データベースを更新すると、デットロックが発生したため調べてみました。

session.update()
transaction.commit()
session.close()
の順番でアクセスを行うと、commitを呼び出した時点でデットロックが発生しました。

session.update()
transaction.commit()
session.flush()
session.close()
の順番でアクセスを行うと、flushを呼び出すとno transaction is in progressのエラーが起きました。

session.update()
session.flush()
transaction.commit()
session.close()
の順番でアクセスを行うと、正常にアクセスできました。

flushメソッド

管理されているEntityに対して行われた操作を、リレーショナルデータベースに強制的に反映するためのメソッド。
EntityManagerのメソッドとして提供されており、蓄積された未反映の操作をリレーショナルデータベースに対して実行する。
通常、リレーショナルデータベースへの反映は、トランザクションコミット時に行われるが、コミットより前に反映する必要がある場合は、メソッドを使用する。

Hibernateは永続化データをキャッシュします。
実際には、データベースにはリアルタイムに処理が施されているわけで、いざ save するときにはデータベースのデータと同期が取れていない可能性があります。
これを防止するのが flush の役割です。