さまざまなJavaクライアント用にRMIベースのデータサービスサーバーを設計しています。クライアントはRMIを使用してリモートでCRUD操作を実行し、サーバーのORMにはJPAを使用する予定です。
一部のRMIは、実装がスレッドセーフであることを要求していることを知っているので、EntityManager
usingを注入することを計画してい@PersistenceContext
ます。2つの質問があります。
- スプリングは
EntityManager
注入されたスレッドを安全にしますか、それとも必要に応じて注入EntityManagerFactory
して呼び出すcreateEntityManager
必要がありますか? - メソッドコードがスレッドセーフであることが保証されている場合でも、同期を確認する必要がありますか?
RMI仕様による
- リモートリクエストが着信すると、メソッド呼び出しをカプセル化するリクエストオブジェクトにすぐにデマーシャルされます。RemoteCallインターフェースを実装するクラスのインスタンスであるこの要求オブジェクトには、ソケットの出力ストリームへの参照があります。つまり、RMIはソケットを共有しますが、ソケットは一度に1つのリモートメソッド呼び出しにのみ使用されます。
- ソケットからリクエストを受け取ったスレッドは、メソッド呼び出しの対象となるリモートオブジェクトを見つけ、そのリモートオブジェクトに関連付けられているスケルトンを見つけ、そのスケルトンのdispatch()メソッドを呼び出します。ディスパッチメソッドには次の署名があります。
- public void dispatch(java.rmi.Remote obj、java.rmi.server.RemoteCall call、int opnum、long hash)はjava.lang.Exceptionをスローします
- スケルトンのdispatch()メソッドは、サーバー上で適切なメソッドを呼び出します。これは、あなたが書いたコードが実際に実行される場所です。
- serverメソッドは値を返し、最終的には元の要求が受信されたソケットを介して伝播されます。
プロセス定義は、コードの多くの分離された呼び出しスタックがRMI環境で作成される可能性があることを示唆していると思います。したがって、RMIではコードがスレッドセーフである必要がありますね。