Spring嵌套事务

新手上路,请多包涵

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

 @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

 @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 方法中启动的所有者事务。现在,如果出现任何异常,任何更改都会回滚。

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

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

原文由 alexanoid 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 724
2 个回答

本文档涵盖了您的问题 - https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/data-access.html#transaction-declarative-annotations

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

但是,可以选择切换到 AspectJ 模式

原文由 Jakub Bibro 发布,翻译遵循 CC BY-SA 4.0 许可协议

update 方法中的事务注释如果从同一类的某个方法调用,Spring 事务基础结构将不会被视为。有关 Spring 事务基础结构如何工作的更多理解,请参阅

原文由 Shailendra 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题