了解 EJB3/JPA 容器级事务和隔离级别 [英] Understanding EJB3/JPA container-level transactions and isolation level

查看:21
本文介绍了了解 EJB3/JPA 容器级事务和隔离级别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Consider this simplified view of some code with which I'm working:

@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().在这种情况下,我们使用容器管理的事务.

I've set the TransactionAttribute annotation to MANDATORY at the class-level. I understand this to mean that all methods such as doSomething() must be invoked within a supplied transaction. We are using container-managed transactions in this case.

TransactionAttributeSecondEjbTypeThirdEjbType 中根本没有使用......无论是在类还是方法级别.我理解这意味着 secondEjb.doSomething()thirdEjb.doSomething() 都将在为 firstEjb.doSomething().

The TransactionAttribute is not used at all in SecondEjbType or ThirdEjbType... neither at the class nor method level. I understand this to mean that secondEjb.doSomething() and thirdEjb.doSomething() will both operate within the transaction supplied for firstEjb.doSomething().

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

However, I'm seriously missing out on something! As indicated by the code comments... secondEjb writes data to a database, and thirdEjb reads that data as part of its operation. Since all of this is running within the same transaction, I would not expect there to be any issues with isolation levels. However, for whatever reason the secondEjb database write isn't visible to thirdEjb.

我已经将跟踪一直调到最大,显然没有异常、错误或回滚问题……初始写入对后续读取根本不可见.我并没有声称自己是世界上最伟大的事务管理大师……我是否遗漏了一些明显的东西,或者我的概念理解是否基本正确,问题可能出在其他地方?

I've turned tracing all the way up to the max, and there's apparently not an exception or error or rollback at issue... the initial write simply isn't visible to the subsequent read. I don't claim to be the world's greatest guru in transaction management... have I missed something obvious, or is my conceptual understanding basically correct and the issue may lie elsewhere?

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

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
   
     jdbc/datasource</jta-data-source>
      
      

      </properties>
   

推荐答案

我从这里的所有答案中学到了很多东西,对人们的感激不尽.但是,我认为我的问题已经使问题变得混乱,以至于最好从不同的问题重新开始.

I've learned a ton from all the answers here, and can't thank people enough. However, I believe that my question has muddied the waters to a point where it might be better to start over with a different question.

从一个 EJB 跳转到下一个并返回似乎与任何事情无关.为了简化问题,我尝试使用与一个 EJB 完全隔离的测试用例.我进入了 secondEjb.doSomething() 方法,该方法将实体持久化到数据库中.在该方法的末尾,我添加了一个 em.flush(),并尝试使用 JPA 查询再次检索实体.

It doesn't appear that jumping from one EJB to the next and back has anything to do with anything. To simplify matters, I tried working with a test case completely isolated to one EJB. I went into that secondEjb.doSomething() method, which persists an entity to the database. At the end of the method, I added an em.flush(), and tried retrieving the entity again with a JPA query.

即使我仍然使用刚刚持久化实体的完全相同的方法,但它对后续查询不可见.我已经在其他地方做了一些额外的研究,它看起来这可能只是事务上下文中 JPA 的正常隔离模式.一个事务启动后,该事务中的其他查询尚无法查看未提交的数据.

Even though I was still in the exact same method where the entity had just been persisted, it was not visible to that subsequent query. I've done some additional research elsewhere, and it looks like this may simply be the normal mode of isolation for JPA in a transactional context. One a transaction is started, additional queries within that transaction don't yet have visibility to uncommitted data.

如果我对链接的 CodeRanch 讨论的总结是准确的,那么 JPA 就糟糕"!:) 无论哪种方式,我都重构了代码以完全避免这个问题.

If my summary of the linked CodeRanch discussion is accurate, then "yuck" on JPA! :) Either way, I've refactored the code to avoid this issue altogether.

这篇关于了解 EJB3/JPA 容器级事务和隔离级别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆