了解EJB3 / JPA容器级别的事务和隔离级别


问题内容

考虑一下我正在使用的一些代码的简化视图:

@Stateless(...)
@Remote(...)
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public class FirstEjbType {

   @EJB(...)
   private SecondEjbType secondEjb;
   @EJB(...)
   private ThirdEjbType thirdEjb;

   public void doSomething() {
      secondEjb.doSomething();  // WRITES SOMETHING TO THE DATABASE
      thirdEjb.doSomething();  // CAN'T SEE THAT SOMETHING IN THE DATABASE!
}

我已经在类级别设置了TransactionAttribute注释MANDATORY。我理解这意味着doSomething()必须在提供的事务中调用诸如之类的所有方法。在这种情况下,我们正在使用容器管理的事务。

TransactionAttribute根本不被用于SecondEjbTypeThirdEjbType…既没有类,也没有方法的水平。我明白这意味着secondEjb.doSomething()thirdEjb.doSomething()会为双方提供的事务中进行操作firstEjb.doSomething()

但是,我严重错过了 某些东西 !如代码注释所示,…
secondEjb将数据写入数据库,然后thirdEjb读取该数据作为其操作的一部分。由于所有这些都在同一个事务中运行,因此我不希望隔离级别有任何问题。
但是,无论出于何种原因,secondEjb数据库写操作都不可见thirdEjb

我一直跟踪到最大,并且显然没有异常,错误或回退问题……后续的读取根本看不到初始写入。我并没有声称自己是交易管理领域的世界上最伟大的专家……我错过了显而易见的事情吗,或者我的概念理解基本上是正确的,而问题可能出在其他地方吗?


更新-johnstok请求的其他信息如下:

  • 我在GlassFish中运行
  • 我不确定“非标准冲洗模式”是什么意思,所以我认为答案是否定的。
  • 我的persistence.xml文件如下所示:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="pu" transaction-type="JTA">
<jta-data-source>jdbc/datasource</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="toplink.cache.shared.default" value="false"/>
</properties>
</persistence-unit>
</persistence>


问题答案:

我从这里的所有答案中学到了很多东西,也无法对别人表示感谢。但是,我认为我的问题使问题陷入泥潭,最好从另一个问题重新开始。

从一个EJB跳到另一个EJB似乎没有任何关系。为了简化问题,我尝试使用完全隔离到一个EJB的测试用例。我进入了该secondEjb.doSomething()方法,该方法将实体保留到数据库中。在该方法的末尾,我添加了一个em.flush(),并尝试通过JPA查询再次检索该实体。

即使我 仍然使用 保留实体的完全相同的方法
,但对于随后的查询却不可见。我在其他地方做了一些其他研究,看起来这可能只是事务上下文中JPA的正常隔离模式。一个事务启动后,该事务中的其他查询尚无法查看未提交的数据。

如果我对链接的CodeRanch讨论的摘要是正确的,那么请在JPA上“ y”!:)无论哪种方式,我都重构了代码,以完全避免此问题。