ユーザースレッド設計ごとに JPA EntityManager を実装する方法を知りたいです。EM は軽量オブジェクトであるため、ユーザー スレッドごとに作成してもオーバーヘッドは発生しません。私が解決したい問題は、(コントローラーを介して) バックエンド サービスへの複数の (並列) JSON/AJAX 呼び出しを含む単一の JSP ページです。
Open EM In View Filter を使用して、Entity Manager (永続化コンテキストを拡張) を使用しています。それはうまく機能しますが、ページごとに 1 つのユーザー スレッド (たとえば、json 呼び出し) がある場合、つまりシリアル方式で em にアクセスする場合のみです。ただし、emインスタンスが共有されているため、複数のスレッドからサービスを呼び出すと、目的が解決されず、奇妙なエラーが発生します(コレクションへのアクセスが共有されることもあれば、接続が閉じられることもあります)。
Spring 3 で JPA を使用し、3.5 を休止状態にしています。以下のように、サービスにエンティティ マネージャー (拡張) を挿入します。
@PersistenceContext(type = PersistenceContextType.EXTENDED)
protected EntityManager em;
私の読み取り専用サービスメソッドには、次のように注釈が付けられています
<tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
他のすべてのメソッドには、次のように注釈が付けられています
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
私はアプリケーション管理を避けたいので、代わりに EntityManagerFactory を注入しませんでした。また、EntityManager をスプリング コントローラーに挿入することを選択した場合、同じコントローラーが 2 つのスレッドから並行して呼び出されると、まだ問題が発生します。
emへのスレッドセーフなアクセスを実現するエレガントな方法はありますか? また、事態をさらに複雑にするエンティティ オブジェクトのロックも避けたいと考えています。
同じページからの複数の ajax 呼び出しは、最新の Web アプリケーションでは非常に一般的な設計であるため、これを実現するためのシンプルで宣言的な方法が必要であると思います (インターセプターなどを使用して休止状態セッションを手動で管理することに戻る必要はありません)。