我有一个设置,其中外部方法调用内部方法。可能会发生这种情况:内部方法将抛出异常,导致回滚。我不希望此异常影响外部方法。为了实现这一点,我在内部方法上使用了@Transactional(propagation=Propagation.REQUIRED_NEW)。
以下是我的代码的简化版本:
public class ServiceAImpl implements ServiceA{
@Autowired
private ServiceB serviceB;
@Transactional(propagation=Propagation.REQUIRED)
public void updateParent(Parent parent) {
update(parent);
serviceB.updateChild(parent);
}
}
public class ServiceBImpl implements ServiceB {
@Transactional(propagation=Propagation.REQUIRED_NEW)
public void updateChild(Parent parent) {
checkIfChildHasErrors(parent.getChild()); //throws RuntimeException if Child has errors
update(parent.getChild());
}
}
public class Parent {
@Version
private Integer version;
private Child child;
//insert getters and setters
}
public class Child {
@Version
private Integer version;
//insert getters and setters
}
我对传播(Propagation)还不是很熟悉,但根据我的理解,由于外部方法(updateParent)使用了Propagation.REQUIRED,而内部方法(updateChild)使用了Propagation.REQUIRED_NEW,它们现在将分别运行在自己的事务中。如果内部方法遇到异常,它将会回滚,但不会引起外部方法的回滚。
当外部方法运行时,它调用内部方法。外部方法被暂停,而内部方法被执行。一旦内部方法完成,由于它是一个不同的事务,所以它会被提交。然后外部方法继续执行并也会被提交为另一个事务。
我遇到的问题是:提交外部方法的过程会触发Child类的乐观锁定(可能是因为版本字段的值在内部方法结束并提交后已经改变)。由于外部方法的Child实例已经过期,提交它将触发乐观锁定。
我的问题是: 有没有一种方法可以防止外部方法触发乐观锁定?
我很惊讶外部方法竟然尝试提交对Child类的更改。我原以为由于内部方法包含在自己的事务中,所以外部方法的事务将不再包括updateChild方法。
我使用的是Spring 3.0.5和Hibernate 3.6.10。