2013-02-28 4 views
3

Я проектирую сервер службы данных на основе RMI для разных Java-клиентов. Клиенты используют RMI для выполнения операций CRUD удаленно, и я планирую использовать JPA для ORM сервера.с использованием JPA в многопоточной архитектуре RMI

Как я знаю, некоторые запросы RMI требуют потокобезопасности, поэтому я планирую ввести EntityManager, используя @PersistenceContext. У меня есть два вопроса.

  1. ли весной сделать EntityManager впрыскивается поточно, или я должен вводить EntityManagerFactory и вызвать createEntityManager при необходимости?
  2. Должен ли я по-прежнему синхронизироваться, если код метода гарантированно является потокобезопасным?

В соответствии со спецификацией RMI

  1. Когда удаленный запрос приходит, он сразу же demarshalled в объект запроса, который инкапсулирует вызов метода. Этот объект запроса, являющийся экземпляром класса , реализующего интерфейс RemoteCall, имеет ссылку на выходной поток сокета . Это означает, что хотя RMI совместно использует сокеты, сокет используется только для одного вызова удаленных методов за раз.
  2. Поток, получивший запрос от сокета, находит целевой объект для вызова метода, находит скелет, связанный с этим удаленным объектом, и вызывает метод отправки скелета(). Способ доставки имеет следующую подпись:
  3. общественного недействительными отправка (java.rmi.Remote OBJ, java.rmi.server.RemoteCall вызова, внутр opnum, длинный хэш) бросает java.lang.Exception
  4. скелета Метод dispatch() вызывает правильный метод на сервере. Это , где код, который вы написали, фактически выполнен.
  5. Метод сервера возвращает значение, которое в конечном итоге распространяется через сокет , на котором был получен исходный запрос.

Я думаю, что определение процесса предполагает, что в среде RMI может быть создано множество разделов вызовов нашего кода. поэтому RMI требует, чтобы код был потокобезопасным, верно?

+0

Вы определенно используете Spring? Если это так, вы можете добавить тег [tag: spring]. –

+0

«Поскольку я знаю, что реализация RMI-запросов является потокобезопасной», я думаю, что вы имеете в виду, что RMI * не делает никаких гарантий в отношении потоковой передачи, и поэтому * требует, чтобы ваши реализации удаленных методов были потокобезопасными. Но это не то, что вы на самом деле сказали. – EJP

+0

@TomAnderson tag изменен, спасибо – Korben

ответ

3

Когда вы экспортируете объект через RMI, он должен иметь дело с несколькими потоками, даже если у вас есть только один клиент для объекта. Вот почему: поток, на котором вы создаете удаленный объект, определенно отличается от потока, который обрабатывает удаленные вызовы.

Таким образом, если вы введете EntityManager во время создания удаленного объекта, он будет введен в другой поток, чем тот, который он использует во время удаленного вызова. Тем не менее, EntityManager может использоваться только в одном потоке и, более конкретно, в потоке, на котором был создан. Например, с Hibernate ваш EntityManager не будет работать, если это не так.

Для того, чтобы создать EntityManager, необходимо использовать EntityManagerFactory. Чтобы свернуть EntityManager творениями, вы можете сохранить EntityManager в ThreadLocal.

0

RMI требует, чтобы код был защищен потоками, верно?

Странная вы задаете вопрос, который уже был дан ответ в комментариях, но независимо от того, что вы цитированной выше есть гораздо более короткий кусок в RMI Specification #3.2, который говорит, что именно:

«а для реализации удаленного объекта необходимо убедиться, что его реализация является потокобезопасной ».

+0

Я пытаюсь понять, правильно ли понял стек вызовов. – Korben

+0

@Korben Какой стек вызовов? – EJP

Смежные вопросы