我确信我遗漏了什么,但我不知道到底是什么。。。
给出以下片段:
@Service
public class MyClass {
private MyClass self;
private UserRepository userRepository;
private ApplicationContext applicationContext;
@PostConstruct
private void init() {
self = applicationContext.getBean(MyClass.class);
}
@Transactional
public void doA(User user) {
...
if (condition) {
self.doB(user);
throw new SecurityException();
}
user.setRandomField("x");
userRepository.save(user);
}
@Transactional(value = Transactional.TxType.REQUIRES_NEW)
public void doB(User user) {
...
userRepository.save(user);
}
}
关于@Transactional
,我所知道的是,如果使用它,调用repository.save(entity)
是多余的。
我试图做的是从事务性方法处理一个实体,如果存在中断条件,则调用一个新方法(用REQUIRES_NEW
注释(,该方法将更新实体的一些字段并保存它。然后根方法(doA
(抛出异常。仅供参考:在这种情况下,@Transactional(dontRollbackOn = SecurityException.class)
不是一个选项。
为了使用这种提交机制,我不是只用一个方法创建一个新的bean,而是将当前bean注入一个名为self
的变量中,因此我可以使用bean代理进行事务管理。
奇怪的是,如果我从doB
中删除save
调用,当doA
事务由于SecurityException
而回滚时,doB
执行的更改也会回滚。但如果我把它放进去,它就会像预期的那样发挥作用。
我是做错了什么还是错过了什么?
谢谢!
尽量不要在doB((中传递User实例。而是传递一个Id,并在内部从repo中读取用户。我不确定在不同会话之间如何处理附加的实体。