开发者社区> 问答> 正文

Seata不支持DynamicDataSource吗

目前分布式事务应用中使用的是动态数据源,通过对动态数据源A和B的操作发现可以正常插入回滚日志到对应数据源的undo_log表中,但是分布式事务回滚和提交时无法正确路由到对应的数据源对回滚日志和业务数据进行操作 场景描述: 应用1::事务参与方,通过动态数据源连接数据库,有默认数据源 应用2:事务发起方,无数据源配置,调用应用1的接口,通过传参动态对数据源进行操作 数据源A:业务表person 数据源B:业务表user 数据源C:默认数据源,seata-server配置此数据源,global_table, branch_table, lock_table在这

场景1:应用2通过调用两次应用1的dubbo接口进行A和B的数据库操作

新增person成功,新增user成功 数据源A和B分别插入一条undo_log 提交全局事务时,应用1报错:数据源C的undo_log表找不到(C里没有undo_log表) 数据源A和B的undo_log都没有删除 场景2:应用2通过调用两次应用1的dubbo接口进行A和B的数据库操作

新增person成功,新增user失败(主键冲突) 数据源A插入一条undo log 回滚全局事务时,应用1报错: 数据源C的undo_log表找不到 lock_table插入一条数据,但是resource_id的数据源为C(我认为应该为A) 全局事务回滚失败,A的undo log没有删除,person表的数据没有删除,C的lock_table的对应数据也没有删除 以下为报C数据源的undo_log找不到的堆栈信息 If there is an exception, please attach the exception trace:

2019-08-21 15:57:09.469  INFO 8568 --- [atch_RMROLE_8_8] io.seata.rm.AbstractRMHandler            : Branch committing: 172.16.68.197:8091:2020086258 2020086260 jdbc:mysql://172.16.68.118:3306/zhttest null
2019-08-21 15:57:09.469 ERROR 8568 --- [atch_RMROLE_7_8] druid.sql.Statement                      : {conn-10001, pstmt-20433} execute error. SELECT * FROM undo_log WHERE branch_id = ? AND xid = ? FOR UPDATE

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'zhttest.undo_log' doesn't exist
	at sun.reflect.GeneratedConstructorAccessor46.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
	at com.mysql.jdbc.Util.getInstance(Util.java:386)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2825)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2156)
	at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2323)
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3188)
	at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeQuery(FilterEventAdapter.java:465)
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3185)
	at com.alibaba.druid.wall.WallFilter.preparedStatement_executeQuery(WallFilter.java:641)
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3185)
	at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeQuery(FilterEventAdapter.java:465)
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3185)
	at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.executeQuery(PreparedStatementProxyImpl.java:181)
	at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeQuery(DruidPooledPreparedStatement.java:228)
	at io.seata.rm.datasource.undo.UndoLogManager.undo(UndoLogManager.java:154)
	at io.seata.rm.datasource.DataSourceManager.branchRollback(DataSourceManager.java:185)
	at io.seata.rm.AbstractRMHandler.doBranchRollback(AbstractRMHandler.java:124)
	at io.seata.rm.AbstractRMHandler$2.execute(AbstractRMHandler.java:68)
	at io.seata.rm.AbstractRMHandler$2.execute(AbstractRMHandler.java:64)
  at io.seata.core.exception.AbstractExceptionHandler.exceptionHandleTemplate(AbstractExceptionHandler.java:117)
	at io.seata.rm.AbstractRMHandler.handle(AbstractRMHandler.java:64)
	at io.seata.rm.DefaultRMHandler.handle(DefaultRMHandler.java:63)
	at io.seata.core.protocol.transaction.BranchRollbackRequest.handle(BranchRollbackRequest.java:35)
	at io.seata.rm.AbstractRMHandler.onRequest(AbstractRMHandler.java:149)
	at io.seata.core.rpc.netty.RmMessageListener.handleBranchRollback(RmMessageListener.java:81)
	at io.seata.core.rpc.netty.RmMessageListener.onMessage(RmMessageListener.java:71)
	at io.seata.core.rpc.netty.AbstractRpcRemotingClient.dispatch(AbstractRpcRemotingClient.java:166)
	at io.seata.core.rpc.netty.AbstractRpcRemoting$3.run(AbstractRpcRemoting.java:371)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)

展开
收起
一人吃饱,全家不饿 2021-02-02 10:50:59 5212 0
来自:阿里开源
1 条回答
写回答
取消 提交回答
  • 看起来是没有代理所有数据源, 需要代理每个数据源,然后Seata可以在回滚时正确路由。

    您可以参考配置文件 DataSourceProxyConfig.java 以获得更多详细信息。

    2021-02-02 11:26:20
    赞同 展开评论 打赏
来源圈子
更多
收录在圈子:
+ 订阅
阿里巴巴相信开源的世界里人人贡献代码,人人获得收益,共同创造一个互帮互利的社区,促进技术进步和发展。
问答排行榜
最热
最新

相关电子书

更多
Nacos架构&原理 立即下载
《Seata 1.3 新特性以及如何参与社区》 立即下载
Dubbo分布式服务治理实战 立即下载