春季嵌套交易 [英] Spring nested transactions

查看:98
本文介绍了春季嵌套交易的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Spring Boot项目中,我实现了以下服务方法:

In my Spring Boot project I have implemented following service method:

@Transactional
public boolean validateBoard(Board board) {
    boolean result = false;
    if (inProgress(board)) {
        if (!canPlayWithCurrentBoard(board)) {
            update(board, new Date(), Board.AFK);
            throw new InvalidStateException(ErrorMessage.BOARD_TIMEOUT_REACHED);
        }
        if (!canSelectCards(board)) {
            update(board, new Date(), Board.COMPLETED);
            throw new InvalidStateException(ErrorMessage.ALL_BOARD_CARDS_ALREADY_SELECTED);
        }
        result = true;
    }
    return result;
}

在此方法内部,我使用了另一种称为update的服务方法:

inside of this method I use another service method which is called update:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public Board update(Board board, Date finishedDate, Integer status) {
    board.setStatus(status);
    board.setFinishedDate(finishedDate);

    return boardRepository.save(board);
}

我需要以update方法提交对数据库的更改,而与以validateBoard方法启动的所有者事务无关.现在,任何更改都会在出现异常的情况下回滚.

I need to commit changes to database in update method independently of the owner transaction which is started in validateBoard method. Right now any changes is rolling back in case of any exception.

即使使用@Transactional(propagation = Propagation.REQUIRES_NEW),它也不起作用.

Even with @Transactional(propagation = Propagation.REQUIRES_NEW) it doesn't work.

如何在Spring中正确执行此操作并允许嵌套事务?

How to correctly do this with Spring and allow nested transactions ?

推荐答案

此文档涵盖了您的问题-

This documentation covers your problem - https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/data-access.html#transaction-declarative-annotations

在代理模式(默认)下,仅拦截通过代理传入的外部方法调用.这意味着自调用实际上是目标对象中调用目标对象另一种方法的方法,即使调用的方法标记有@Transactional,也不会在运行时导致实际事务.另外,必须完全初始化代理以提供预期的行为,因此您不应在初始化代码(即@PostConstruct)中依赖此功能.

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional. Also, the proxy must be fully initialized to provide the expected behaviour so you should not rely on this feature in your initialization code, i.e. @PostConstruct.

但是,有一个选项可以切换到AspectJ模式

However, there is an option to switch to AspectJ mode

这篇关于春季嵌套交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆