我正在使用Spring 4
,JPA
和Hibernate 5
。我的服务如下:
@Transactional(rollbackFor = Exception.class)
public methodA() {
// do some stuff
methodB();
}
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public methodB() {
try {
methodC();
} catch (Exception e) {
// only log
}
}
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public methodC() {
// do some stuff
}
我想要达到的目的是:当调用methodA
时,在调用methodB
之前执行的所有操作都应该保留,与之后发生的事情无关。出于这个原因,我添加了methodB
,其唯一目的是创建一个新事务,因此如果methodC
的事务回滚,methodA
的原始事务也不会回滚。总而言之,我希望第一个事务提交,第二个事务在发生故障时回滚。请注意,methodC
无法以任何方式更改。
但是这段代码不起作用,我仍然得到例外:"TransactionException: Transaction was marked for rollback only; cannot commit"
关于我做错的任何想法?
答案 0 :(得分:4)
我使用的是Spring 4,JPA和Hibernate 5.我的服务如下:
因此,您在同一服务
中使用了三种方法这一亮点很重要,因为Spring AOP的工作原理。
如果您在同一个类中调用方法,则其他方法不会被@Transaction
代理,因此他们仍然使用methodA
的相同事务。
因此,当rollbackOnly
methodB
时,您会看到异常
所以要解决这个问题:你必须将方法methodB
移动到另一个服务,以便它可以由Spring代理。