You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot中@Transactional注解失效,TransactionManager不工作求助

@Transactional注解事务失效排查(SpringBoot 3.1.1 + Java 17)

问题描述

使用@Transactional注解更新UserEntity的nick字段时,服务层能正常获取URL传入的新nick值,但事务完全不生效。预期UserService的updateProfile方法执行时,TransactionManager会开启事务并生成代理对象更新数据库,实际无任何效果。日志显示TransactionSynchronizationManager.isActualTransactionActive()返回false,且无transactionManager启动日志。该功能之前运行正常,现已确认遵循@Transactional注解使用规则,但问题依旧。

技术环境

  • SpringBoot 3.1.1
  • Java 17

相关代码

UserApiController.java

@Slf4j
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
@Validated
public class UserApiController{

    @EmailAuth
    @PostMapping("/email-auth-completion/{code}")
    public ResponseEntity verifyEmail(@PathVariable("code") String code) {
        log.info("[실행] UserApiController.verifyEmail");
        Map<Object, Object> data = redisUtil.getEmailCertification(code);

        log.info("[정보] " + redisUtil.getEmailCertification(code).toString());
        userService.updateEmailAuth(data);
        return ResponseFormat.RESPONSE_OK;
    }
}

UserService.java

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class UserService {

    @Transactional
    public void updateProfile(ProfileUpdateReqDto reqDto, Long id) {
        log.info("[실행] updateProfile" + id);
        log.info("[정보] 트랜젝션 포함 여부 : " + TransactionSynchronizationManager.isActualTransactionActive());
        log.info("[정보] reqDto.getNick() : " + reqDto.getNick());
        User user = Optional.ofNullable(userRepository.findByid(id)).orElseThrow(
                () -> new CustomException(ErrorCode.NOTFOUND_USER))
                .get();

        log.info("[정보] user : " + user.toString());

        if (checkNickDuplication(reqDto.getNick())) {
            throw new CustomException(PARAM_NICK, ErrorCode.DUPLICATE_USER_NICK);
        }

        log.info("[정보] 트랜젝션 포함 여부 : " + TransactionSynchronizationManager.isActualTransactionActive());
        user.updateProfile(
                reqDto.getProfileImage(),
                reqDto.getNick()
        );
    }
}

排查方向与解决方案

  1. 检查事务管理器是否正常初始化
    在配置文件中添加DEBUG级别的日志,查看事务管理器的启动日志:

    logging.level.org.springframework.transaction=DEBUG
    logging.level.org.springframework.orm.jpa=DEBUG
    

    若没有事务管理器初始化日志,检查是否通过spring.autoconfigure.exclude排除了DataSourceTransactionManagerAutoConfiguration,或手动配置的事务管理器存在错误。

  2. 确认代理模式与方法可见性
    SpringBoot 3默认使用CGLIB代理,需确保:

    • UserService类不是final类
    • updateProfile方法不是final方法(final方法无法被CGLIB代理,导致事务注解失效)
  3. 排查内部方法调用问题
    检查是否存在UserService内部无@Transactional注解的方法调用updateProfile的情况,这种场景下不会触发代理,事务无法生效。必须通过Spring容器注入的代理对象调用该方法。

  4. 验证@Transactional注解配置
    确认注解未指定错误的transactionManager Bean名称;多数据源场景下需明确指定对应事务管理器。

  5. 检查组件扫描范围
    确认UserService所在包被Spring组件扫描覆盖,@Service注解被正确识别,否则不会生成事务代理对象。

内容的提问来源于stack exchange,提问作者stonage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 13:28:45