Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 理解EJB中的JTA:不刷新_Jpa_Ejb_Eclipselink_Jta - Fatal编程技术网

Jpa 理解EJB中的JTA:不刷新

Jpa 理解EJB中的JTA:不刷新,jpa,ejb,eclipselink,jta,Jpa,Ejb,Eclipselink,Jta,因此,我用@TransactionAttribute(TransactionAttributeType.REQUIRED)在类级别对这个EJB进行注释,这样每个方法都应该在事务中执行,除非我重写这个行为,当事务被提交时,数据应该被刷新,对吗?到现在为止,一直都还不错。 所以现在我有了一个公共用户查找(字符串电子邮件)方法,用@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)注释,所以这个方法不会在事务中执行,因为它只获取数据

因此,我用
@TransactionAttribute(TransactionAttributeType.REQUIRED)
在类级别对这个EJB进行注释,这样每个方法都应该在事务中执行,除非我重写这个行为,当事务被提交时,数据应该被刷新,对吗?到现在为止,一直都还不错。 所以现在我有了一个
公共用户查找(字符串电子邮件)
方法,用
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
注释,所以这个方法不会在事务中执行,因为它只获取数据

好的,我正在测试我的应用程序,我有一个booter方法,它使用ejb创建两个实体,然后使用find方法获取一个实体。 在我看来,应该发生什么:

->我创建实体1,调用在事务中执行的
save(User u)
。它提交时,数据被刷新

->对另外两个实体重复此步骤。当事务提交时,数据被刷新

->此时,我的二级缓存(使用Eclipselink)和数据库中应该有3个实体

->我调用
find(字符串电子邮件)
方法。它找到一个实体,返回它,没有异常,我的代码执行得很好,我很兴奋,我打开一瓶啤酒,我不需要在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>

org.eclipse.persistence.jpa.PersistenceProvider
贡品
假的
全部的

除了在搜索时没有找到实体之外,没有引发任何异常,在此之后,缓存将刷新到数据库。

我猜您没有正确配置内容。包括persistence.xml以及正在使用的应用程序服务器和数据库

如果您使用的是JTA或RESOURCE_LOCAL,那么您应该使用JTA,并且应该在persistence.xml中设置目标服务器

还要检查是否有任何错误。如果发生错误,则事务将回滚


不支持通常不是一个好主意,这意味着如果在事务中调用此方法,将引发异常。这可能就是正在发生的情况。

添加它,它将显示何时执行语句以及何时提交事务。由于不支持挂起事务,因此只有在先前的事务已提交的情况下才能“查找”数据。很可能您的save方法被包装在一个更大的事务中,而find方法正在挂起该事务。Flush不会更改此项,因为此数据仍处于事务隔离状态


尝试使用REQUIRES_NEW将保存方法放入它们自己的事务中,在完成时提交。

好的,提交事务不需要Eclipselink刷新数据。这就是原因。我认为这是一种非常丑陋的行为。Eclipselink可以在需要时刷新数据。我也有一些问题。例如,当使用@PrePersist或@PreUpdate时,不保证在提交事务时发生这种情况。例如,在计算某些统计数据时,您不能在同一事务中使用它们,因为Eclipselink可以在事务已经完成时进行处理


必须使用所使用的实体才能使em.persist()持久化。以防执行数据库查询。刷新实体需要Eclipselink,因为查询可能不正确。但是在尝试扩展应用程序时,使用em.flush()会导致一些非常糟糕的性能问题。

这是“从不”属性,不受支持会挂起事务(如果处于活动状态),或者如果未处于活动状态,则会在事务外执行该方法。它使方法成为非事务性的。如果在事务中调用该方法,则不会引发异常。那么,如果使用“从不”,是否会收到异常?@Chris我收到异常是!它说:
javax.ejb.EJBException:ejb不能在全局事务中调用
,您是对的,事务没有提交,而是启动了“全局”事务。为什么?这是某种优化吗?我从一个请求范围的CDIBean调用,该bean是非事务性的。我不知道发生了什么事