Coj*_*nes 3 java spring hibernate jpa-2.0
我正在使用Spring/JPA2/hibernate代码:
class A {
@Autowired
B b;
@RequestMapping("/test")
public void test(final HttpServletRequest r1, HttpServletResponse r2) throws ... {
b.inner(); // Works
b.outer(); // javax.persistence.TransactionRequiredException:
// no transaction is in progress ... :|
}
@Component
class B {
@PersistenceContext
EntityManager em;
public void outer() { inner(); }
@Transactional
public void inner() { em.flush(); }
}
Run Code Online (Sandbox Code Playgroud)
为什么inner()只有在间接调用时才会松散交易?
在代理模式(默认设置)下,只拦截通过代理进入的外部方法调用.这意味着实际上,自调用目标对象中的一个方法调用目标对象的另一个方法,即使被调用的方法用@Transactional标记,也不会在运行时导致实际的事务.
如果您希望自我调用也包含在事务中,请考虑使用AspectJ模式(请参阅下表中的mode属性).在这种情况下,首先不会有代理; 相反,目标类将被编织(即,它的字节代码将被修改),以便在任何类型的方法上将@Transactional转换为运行时行为.
该@Autowired参考B b(内部类A),被包裹着的Spring AOP事务感知代理.
当b.inner()被调用时,要调用它的交易意识的实例,并将其标记为@Transactional.因此,启动了Spring托管事务.
在b.outer()调用时,它也在事务感知实例上,但事实并非如此 @Transactional.因此,Spring管理的事务未启动.
一旦你在里面的调用outer()调用inner()是不通过交易感知代理下去,它被直接调用.它是一样的this.inner().由于您是直接调用它,而不是通过代理调用它,因此它没有Spring事务感知语义.
由于没有启动任何事务,因此导致了TransactionRequiredException.
可能的解决方案包括制定方法outer() @Transactional.
@Transactional
public void outer() { inner(); }
Run Code Online (Sandbox Code Playgroud)
或者整个班级 @Transactional.
@Transactional
@Component
class B {
@PersistenceContext
EntityManager em;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1549 次 |
| 最近记录: |