JPA: вопрос о entityManager.joinTransaction - PullRequest
3 голосов
/ 15 июля 2011

Допустим, мы объявляем менеджер приложений , управляемый приложением, как показано ниже (похожую версию можно найти по адресу: http://download.oracle.com/docs/cd/E19798-01/821-1841/bnbqy/index.html):

@PersistenceUnit EntityManagerFactory emf;
@Resource UserTransaction utx;
protected void doPost(HttpServletRquest req,...)
   em = emf.createEntityManager();
   try {
     utx.begin(); //(1)
     em.persist(SomeEntity);
     utx.commit();
   } catch (Exception e) {
     utx.rollback();
   }

Пока код работает нормально, есть несколько слайдов от архитекторов SUN (например: http://www.scribd.com/doc/6616366/TS49452007JavaEE) заявляет, что блок глючит и после строки следует добавить "em.joinTransaction ()") (1) (слайд № 50).

Если происходят исключения, постоянный контекст будет несовместим , и мы просто закроем em , так что здесь может быть потенциальная ошибка?

Любые предложения, по которым я скучаю, действительно приветствуются. Спасибо.

Ответы [ 2 ]

4 голосов
/ 15 июля 2011

Да, код, который вы показываете, является ошибочным с точки зрения JTA.

Вы должны сообщить EM, что хотите, чтобы он был частью распределенной транзакции, вызвав em.joinTransaction ().Если вы не вызовете этот метод, пользовательская транзакция и транзакция EM будут отключены.Javadocs этого метода состояния:

Укажите EntityManager, что транзакция JTA активна.

Вы также можете видеть, что EM не нужно запускатьтранзакция, когда вы вызываете em.joinTransaction.Если вы не были в среде JTA, вам нужно было бы вызвать em.getTransaction (). Begin () и em.getTransaction.commit (), но, поскольку вы находитесь в транзакции JTA, UserTransaction отвечает за запуск, коммит или откат.


По поводу второго вопроса, нет проблем с кодом, который у вас там, как будто есть исключение, вы вообще не вызываете EM. НО если возникла исключительная ситуация, единственный метод, который вы можете (и должен) вызывать, это em.close ().Если вы попытаетесь сделать что-то еще, например, вызвать em.find (), EM выдаст исключение InvalidStateException.

Надеюсь, то, что я написал, понятно ... JTA - сложный монстр.

0 голосов
/ 18 июля 2011

Я думаю, что проблема с приведенным выше кодом заключается в том, что иногда не работает.Хотя он и работал в моем испытании (я пробовал с Glassfish / EclipseLink), он может не работать в других случаях (например: http://netbeans.org/bugzilla/show_bug.cgi?id=90031).

Единственное, чего мне не хватало (и на него ответил @Augusto)используя em.joinTransaction, мы не только спрашиваем, что «постоянный контекст», созданный em, совпадает с utx, но и регистрирует em в utx, чтобы при utx.commit em сбрасывал содержимое в db.

Я доволен ответом @Augusto, но, поскольку я не могу войти в учетную запись, создавшую вопрос, я не могу нажать кнопку "принять", извините за это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...