JTA事务多数据源建表:The command cannot be executed when global transaction is in the ACTIVE state

本文解决了在多数据源环境下,使用Bitronix Transaction Manager时出现的XAER_RMFAIL错误。通过调整事务传播行为并使用JDBC直接提交,成功绕过了Hibernate在特定情况下的限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述:

我遇到这个错误的场景是多数据源,读取第一个数据源的配置表信息,再切换到第二个数据源创建表的时候会报错(主数据源创建表不会报错,第二个数据源增删改查正常):XAER_RMFAIL: The command cannot be executed when global transaction is in the  ACTIVE state。

再交代一下数据源,事务方面的情况:两个数据源,使用hibernate的sessionFactory管理,事务由于项目使用了activity,使用的是JtaTransactionManager,具体的transactionManager为:bitronixTransactionManager。

解决过程:

报错提示很清晰明了global transaction 在active状态,网上查了不少资料,都是大同小异到处转抄的,并没有实际解决问题,无奈自己倒腾。

既然是事务,那就涉及事务传播,在org.springframework.transaction.TransactionDefinition中定义了几种事务传播行为,最开始想到的是自己手动提交事务,于是设置事务传播属性为:PROPAGATION_REQUIRES_NEW,但是问题依然存在,于是想到使用PROPAGATION_NOT_SUPPORTED,但是使用session提交的时候会抛出:找不到当前JTA transaction的异常。那我们最终可以绕过hibernate,使用jdbc来直接提交,问题得到解决。

下面附上关键代码:

		JtaTransactionManager tm = BeanFactory.getBean(BeanAttribute.TRANSACTION_MANAGER);
		DefaultTransactionDefinition def = BeanFactory.getObject(DefaultTransactionDefinition.class);

		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
		TransactionStatus status = tm.getTransaction(def);
		Connection connection=null;
		Statement statement=null;
		try {
			PoolingDataSource dataSource = BeanFactory.getBean("dataSource.1");
			connection = dataSource.getConnection();
			statement = connection.createStatement();
			statement.execute("CREATE TABLE second_datasource_table (" +
					"  `UUID` varchar(32) COLLATE utf8_bin NOT NULL," +
					"  `OPERSTATUS` varchar(1) COLLATE utf8_bin DEFAULT NULL," +
					"  PRIMARY KEY (`UUID`)" +
					") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=COMPACT;");
			tm.commit(status);
		} catch (Exception e) {
			tracer.error(e);
			tm.rollback(status);
		} finally {
			if(statement!=null){
				try {
					statement.close();
				} catch (SQLException e) {
					tracer.error(e);
				}
			}
			if(connection!=null){
				try {
					connection.close();
				} catch (SQLException e) {
					tracer.error(e);
				}
			}
		}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值