Понимание JTA в EJB: не смывает - PullRequest
4 голосов
/ 22 марта 2012

Итак, этот EJB аннотирован на уровне класса с помощью @TransactionAttribute(TransactionAttributeType.REQUIRED), так что каждый метод должен выполняться в транзакции, если только я не переопределю это поведение, когда транзакция фиксируется, данные должны быть сброшены, верно? Все идет нормально. Итак, теперь у меня есть метод public User find(String email), помеченный @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED), поэтому этот метод не выполняется в транзакции, поскольку он только выбирает данные.

Хорошо, поэтому я тестирую свое приложение, и у меня есть метод booter, который создает пару сущностей с помощью ejb, а затем использует метод find для его получения. Что, на мой взгляд, должно произойти:

-> Я создаю сущность 1, вызывающую save(User u), которая выполняется в транзакции. Это фиксирует, данные сбрасываются.

-> Повторите этот шаг еще с 2 объектами. их транзакции фиксируются, данные сбрасываются.

-> На данный момент у меня должно быть 3 объекта в моем кеше L2 (используя Eclipselink) и в моей базе данных.

-> Я вызываю метод find(String email). Он находит сущность, возвращает ее, без исключения, и мой код выполняется хорошо, я волнуюсь, открываю пиво, и мне не нужно задавать вопрос в stackoverflow.

Что на самом деле происходит:

-> Я создаю все 3 объекта. Не исключение.

-> Я вызываю метод find(String email), он вызывает EjbException, потому что не находит сущность, отладка Я обнаруживаю, что при вызове этого метода база данных пуста, данные не сбрасываются (даже если я вызываю метод flush при явном создании сущностей, которые в любом случае не должны быть необходимыми). Он генерирует исключение EJbException, мой код останавливается, я снова проверяю базу данных, и СЕЙЧАС там находятся объекты, как только возникло исключение, потому что их там не было. Если я удаляю @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) из метода find, в результате чего он выполняет поиск внутри транзакции, мой код работает.

-> Я не открываю пиво.

Так что теперь серьезно, что происходит? Почему мне нужно искать сущность внутри транзакции, иначе она ничего не сбрасывает?

РЕДАКТИРОВАТЬ: Постоянство Единица:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="TribunalExpedientes" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>tribunalexpedientes</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <shared-cache-mode>ALL</shared-cache-mode>
     <properties>
      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
     </properties>
  </persistence-unit>
</persistence>

Исключение не возникло, за исключением того, что при поиске сущность не была найдена, после чего кэш сбрасывается в базу данных.

Ответы [ 3 ]

3 голосов
/ 22 марта 2012

Я предполагаю, что у вас не все настроено правильно. Включите ваш файл persistence.xml, а также сервер приложений и базу данных, которую вы используете.

Используете ли вы JTA или RESOURCE_LOCAL, вам следует использовать JTA и настроить целевой сервер в своем файле persistence.xml.

Также проверьте на наличие ошибок. Если произойдет ошибка, транзакция будет отменена.

NOT_SUPPORTED вообще не является хорошей идеей, это означает, что будет вызвано исключение, если этот метод вызывается в транзакции. Что может быть тем, что происходит.

1 голос
/ 23 марта 2012

Добавить, который покажет вам, когда выполняются операторы и когда транзакция фиксируется.Поскольку NOT_SUPPORTED приостанавливает транзакцию, вы можете «найти» данные, только если предыдущая транзакция была зафиксирована.Скорее всего, ваши методы сохранения обернуты в более крупную транзакцию, которую ваш метод find приостанавливает.Flush не изменит этого, потому что эти данные все еще транзакционно изолированы.

Попробуйте использовать REQUIRES_NEW, чтобы методы сохранения помещали в свои собственные транзакции, которые фиксируются после выполнения.

0 голосов
/ 30 марта 2012

Что ж, для совершения транзакции не требуется Eclipselink для сброса данных. Вот в чем причина. Это на мой взгляд очень уродливое поведение. Eclipselink разрешено сбрасывать данные, когда он хочет это сделать. У меня также были некоторые проблемы с этим. Например. при использовании @PrePersist или @PreUpdate не гарантируется, что это происходит при совершении транзакции. Например. при вычислении некоторых статистических данных вы не можете использовать их в одной и той же транзакции, поскольку Eclipselink может выполнить обработку, когда транзакция уже завершена.

Вы должны использовать сущность, которую используете, чтобы создать em.persist (). В случае, если вы выполняете запрос БД. Eclipselink требуется для очистки объекта, поскольку запрос может быть неправильным. Но вместо этого использование em.flush () вызовет некоторые действительно ужасные проблемы с производительностью при попытке масштабирования приложения.

...