因此,我在此类EJB级注释了@TransactionAttribute(TransactionAttributeType.REQUIRED)
,以便每个方法都应该在事务中执行,除非我重写此行为,当事务提交时,数据将被刷新, 对?到现在为止还挺好。 所以现在我有一个public User find(String email)
方法,用@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
注解,所以这个方法不在事务中执行,因为它只提取数据。了解EJB中的JTA:不刷新
好的,所以我正在测试我的应用程序,并且我有一个引导程序方法,使用ejb创建一对实体,然后使用find方法来获取一个。 在我看来,应该发生什么:
- >我创建的实体1调用save(User u)
它在事务中执行。它承诺,数据被刷新。
- >用2个实体重复此步骤。他们的事务提交,数据被刷新。
- >在这一点上,我应该在我的二级缓存(使用Eclipselink)和我的数据库中有3个实体。
- >我打电话给find(String email)
方法。它找到一个实体,返回它,没有例外,我的代码执行得很好,我很兴奋,打开一个啤酒,我不需要在stackoverflow中提出问题。
实际发生了什么:
- >我创建了所有3个实体。没有例外。我调用find(String email)
方法,它引发了一个EjbException,因为它没有找到实体,调试我发现当调用这个方法时,数据库是空的,没有数据被刷新(即使我当我明确地创建实体时调用flush方法,无论如何它不应该是必需的)。它抛出EJbException,我的代码停止,我再次检查数据库,现在实体在那里,一旦抛出异常,因为它们不在那里。 如果我从find方法中删除@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
,这会导致它在事务内部执行搜索,我的代码就可以工作。
- >我不开啤酒。
所以,现在认真,发生了什么?为什么我需要在事务内部搜索实体,否则它不会刷新任何内容?
编辑:持久性单元:
<?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>
也不例外,除了一说,没有实体已经发现,当我搜索,在这之后,刷新缓存到数据库中提出。
这是“NEVER”属性,NOT_SUPPORTED挂起一个事务(如果处于活动状态)或者如果不活动,它将执行事务外的方法。它使该方法非事务性。如果在事务中调用该方法,它不会引发异常。 – arg20 2012-03-23 11:26:41
那么如果你不使用,你会得到异常吗? – Chris 2012-03-23 13:28:30
@Chris我得到一个异常是!它说:'javax.ejb.EJBException:EJB不能在全局事务中被调用,你是对的,事务没有被提交,insted一个“全局”事务被启动。为什么?这是一种优化?我从RequestScoped CDI bean调用,该bean是非事务性的。我不知道发生了什么事 – arg20 2012-03-23 15:18:26