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

查看:120
本文介绍了了解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.

SecondEjbType 中根本没有使用 TransactionAttribute 或者 ThirdEjbType ...既不是类也不是方法级别。我理解这意味着 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 / persistenceversion =1.0>

     < persistence-unit name = putransaction-type =JTA>

        < jta- data-source> jdbc / datasource< / jta-data-source>

         <排除-不公开的类>假LT; /排除-不公开的类>

         < properties>

             < property name =toplink.cache.shared.defaultvalue = false/>

         < / properties>

     < / persistence-unit>

< / persistence>

推荐答案

我从所有人那里学到了很多东西答案在这里,并不能感谢人们。但是,我相信我的问题已经混淆了这个问题,可能最好从另一个问题重新开始。

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讨论的摘要是准确的,那么yuck 关于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天全站免登陆