记一次Spring事务管理器失效

问题

某天突然发现一直正常的事务突然有异常数据库不回滚了,就算是手动强制回滚也不行。手动做了一个测试。

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> testTest() {
        mdFactoryService.save(new MdFactory().setFactoryNumber("88811").setFactoryDescription("88811"));
        if(true){
            throw new KengicBootNoLogException("运行时异常");
        }

        return Result.OK("OK");
    }

解决路程

  • 首先检查了代码 public啊 回滚指定异常啊 没有被 catch 啊等等。都没问题。

  • 其次查看了数据库的事务机制是否有问题。
BEGIN TRANSACTION;

INSERT INTO md_factory (id,factory_number, factory_description)
VALUES ('1','1', '2');

-- 查看插入是否成功
SELECT * FROM md_factory WHERE factory_number = '1';

-- 回滚事务
ROLLBACK;

-- 再次查询,验证数据是否被回滚
SELECT * FROM md_factory WHERE factory_number = '1';

SELECT name, is_read_only, recovery_model_desc 
FROM sys.databases 
WHERE name = 'kengic-mes-factory';

也正常回滚,没有问题,至此排除数据库问题。

后来发现在项目中只加了@EnableTransactionManagement  启用 Spring 事务管理功能的注解。没有显式的配置事务管理器。

@Configuration
@EnableTransactionManagement
public class TransactionConfig {
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

添加后再次执行测试代码,发现报了一个错

No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 2: rabbitTransactionManager,transactionManager

这个错误表明 Spring 上下文中存在两个 TransactionManager 类型的 Bean,分别是 rabbitTransactionManager transactionManager。由于 Spring 在自动装配时无法确定使用哪个 TransactionManager,因此抛出了 No qualifying bean of type 'org.springframework.transaction.TransactionManager' 的错误

之前可能使用的不是数据库的事务管理器。

解决方法

方法 1:使用 @Primary

@Configuration
@EnableTransactionManagement
public class TransactionConfig {
    @Primary  // 优先注入 DataSourceTransactionManager
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

这样配置后,Spring 会默认使用 DataSourceTransactionManager 来管理数据库事务,而 RabbitTransactionManager 只会用于 RabbitMQ 的事务。

方法 2:在 @Transactional 中指定事务管理器

@Transactional(transactionManager = "transactionManager")  // 使用数据库事务
public void someDbMethod() {
    // 执行数据库相关的操作
}

@Transactional(transactionManager = "rabbitTransactionManager")  // 使用 RabbitMQ 事务
public void someMessageQueueMethod() {
    // 执行消息队列相关操作
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值