了解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
根本不被用于SecondEjbType
或ThirdEjbType
…既没有类,也没有方法的水平。我明白这意味着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”!:)无论哪种方式,我都重构了代码,以完全避免此问题。