Korben
Korben

Reputation: 734

using JPA in multi-thread RMI architecture

I am designing an RMI based data service server for different Java clients. The clients use RMI to perform CRUD operations remotely, and I plan to use JPA for the server's ORM.

As I know some RMI requests implementation to be thread-safe, so I am planning to inject the EntityManager using @PersistenceContext. I have two questions.

  1. Does spring make the EntityManager injected thread safe, or should I inject EntityManagerFactory and call createEntityManager when necessary?
  2. Do I still have to make sure synchronized when method code is guaranteed to be thread safe?

According to the RMI specification

  1. When a remote request comes in, it is immediately demarshalled into a request object that encapsulates the method invocation. This request object, which is an instance of a class implementing the RemoteCall interface, has a reference to the socket's output stream. This means that, although RMI shares sockets, a socket is used only for one remote method invocation at a time.
  2. The thread that received the request from the socket finds the intended remote object for the method invocation, finds the skeleton associated with that remote object, and invokes that skeleton's dispatch( ) method. The dispatch method has the following signature:
  3. public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception
  4. The skeleton's dispatch( ) method invokes the right method on the server. This is where the code you wrote is actually executed.
  5. The server method returns a value, which is eventually propagated back through the socket on which the original request was received.

I think the process definition suggests many separated call stacks of our code could be created in RMI environment. therefore, RMI requires code to be Thread safe, am I right?

Upvotes: 3

Views: 997

Answers (2)

user207421
user207421

Reputation: 310980

RMI requires code to be Thread safe, am I right?

Strange you are are asking a question that has already been answered in comments, but regardless of what you've quoted above there is a much shorter piece in the RMI Specification #3.2 that says exactly that:

"a remote object implementation needs to make sure its implementation is thread-safe."

Upvotes: 0

Ingo Kegel
Ingo Kegel

Reputation: 48070

When you export an object via RMI, it has to deal with multiple threads, even if you just have a single client for the object. Here's why: The thread on which you create the remote object is definitely different from the thread that handles remote invocations.

So if you inject the EntityManager during the creation of the remote object, it will have been injected on a different thread than the one it is used on during a remote call. However, an EntityManager can only be used on a single thread and more specifically on the thread on which is was created. With Hibernate, for example, your EntityManager will not work unless this is the case.

So you have to use an EntityManagerFactory to create the EntityManager on demand. To minimize EntityManager creations, you could store the EntityManager in a ThreadLocal.

Upvotes: 3

Related Questions