CDI @Transactional 与自调用
CDI @Transactional with Self Invocation
环境:
JAVA EE 7
CDI 1.2
野蝇 8.2.0
代码:
我有一个 JAVA class 具有以下方法。
@SessionScoped
@Named("orgBean")
public class OrgBean{
@Transactional
public void doSomething(){
//EM.persist();
//call private method
innerMethod();
}
private void innerMethod(){
EM.persist(); //why is this working ?
}
}
1)doSomething() 方法在事务中运行。该方法调用另一个私有方法innerMethod()。
2)innerMethod() 使用 EM.persist() 调用。
Issue/Query :
1)EM.persist() 是如何工作的?
2) 我试图将此与 Spring 框架联系起来。由于 CDI 使用代理(方法调用 OrgBean.doSomething 将通过 PROXY 进行)并且 innerMethod 是自调用,因此 EM.persist() 调用将如何工作,因为 innerMethod() 不会 运行 在交易中?
3)如有错误请指正
innerMethod()
中的代码在调用 doSomething()
开始的事务中运行,并在 doSomething()
方法 returns 时结束。
- 事务代理的
doSomething()
方法被调用
- 代理开始交易
- 代理调用 OrgBean 的实际
doSomething()
方法
- OrgBeans 的
doSomething()
可以为所欲为,包括调用其他方法。代理不关心,甚至不知道它
- OrgBeans 的
doSomething()
方法 returns 到代理的 doSomething() 方法包装器
- 事务代理提交事务。
在伪代码中,代理基本上做了以下事情:
public void doSomething() {
startTransaction();
try {
orgBean.doSomething();
commitTransaction();
}
catch (RuntimeException e) {
rollbackTransaction();
throw e;
}
}
比实际情况要复杂一些,但你应该明白了。
环境:
JAVA EE 7
CDI 1.2
野蝇 8.2.0
代码:
我有一个 JAVA class 具有以下方法。
@SessionScoped
@Named("orgBean")
public class OrgBean{
@Transactional
public void doSomething(){
//EM.persist();
//call private method
innerMethod();
}
private void innerMethod(){
EM.persist(); //why is this working ?
}
}
1)doSomething() 方法在事务中运行。该方法调用另一个私有方法innerMethod()。
2)innerMethod() 使用 EM.persist() 调用。
Issue/Query :
1)EM.persist() 是如何工作的?
2) 我试图将此与 Spring 框架联系起来。由于 CDI 使用代理(方法调用 OrgBean.doSomething 将通过 PROXY 进行)并且 innerMethod 是自调用,因此 EM.persist() 调用将如何工作,因为 innerMethod() 不会 运行 在交易中?
3)如有错误请指正
innerMethod()
中的代码在调用 doSomething()
开始的事务中运行,并在 doSomething()
方法 returns 时结束。
- 事务代理的
doSomething()
方法被调用 - 代理开始交易
- 代理调用 OrgBean 的实际
doSomething()
方法 - OrgBeans 的
doSomething()
可以为所欲为,包括调用其他方法。代理不关心,甚至不知道它 - OrgBeans 的
doSomething()
方法 returns 到代理的 doSomething() 方法包装器 - 事务代理提交事务。
在伪代码中,代理基本上做了以下事情:
public void doSomething() {
startTransaction();
try {
orgBean.doSomething();
commitTransaction();
}
catch (RuntimeException e) {
rollbackTransaction();
throw e;
}
}
比实际情况要复杂一些,但你应该明白了。