正确的Hibernate嵌套事务处理

时间:2020-04-02 12:40:37

标签: java spring hibernate spring-transactions transaction-isolation

我确定我缺少什么,但我不知道到底是什么...

提供以下代码段:

@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事务时,{{ 1}}也将回滚。但是,如果我把它放在那里,它会按预期工作。

我做错了什么还是错过了什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

尝试不要在doB()中传递用户实例。 相反,传递一个ID并从内部从回购中读取用户。我不确定在不同的会话之间如何处理附加的实体。