-
Notifications
You must be signed in to change notification settings - Fork 8.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bugfix: support DataSourceXA using the same connection string #5034
base: develop
Are you sure you want to change the base?
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## develop #5034 +/- ##
==========================================
Coverage 48.85% 48.86%
- Complexity 4184 4187 +3
==========================================
Files 794 795 +1
Lines 28054 28061 +7
Branches 3426 3426
==========================================
+ Hits 13705 13711 +6
- Misses 12910 12914 +4
+ Partials 1439 1436 -3
|
@slievrly This pr need you to help me review |
1.如果所有都在start时,hold链接,那判断oracle和mysql8.0.29以下等需要hold的链接是不是可以去掉了 |
1.只在8.0.29以上及其他mysql,mariadb以外的数据库都会在一阶段close,释放holder |
return; | ||
if (isHeld()) { | ||
if (shouldBeHeld()) { | ||
// if kept by a keeper, just hold the connection. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为在一阶段start之前,keepIfNecessary方法设置了this.shouldBeHeld = true,就一定会走这里的逻辑,那么现在的逻辑就是,所有数据库都会在一阶段hold链接,到二阶段结束才release链接,那感觉判断mysql8.0.29以下和maridb数据库是不是没啥意义了
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
还有一种情况是oracle同库不同用户,一个用户a,拥有三张表,表stock_tbl,account_tbl,order_tbl;一个用户b,拥有对用户a下的account_tbl下的操作权限,同一个服务的前置条件下,jdbcurl相同,TM下调用链是这样的,a1接口是用户a操作stock_tbl表,a2接口是用户b操作account_tbl,a3接口是用户a操作操作order_tbl表,在没有修改前会报XAER_NOTA的问题,修改后不报错,但是如果在二阶段时,前面的链接报错,导致keeper中没有存储对应的东西,通过resourceId获取数据源又获取错误,采用用户a的链接提交用户b的事务,因为我用oracle原生的XA模拟了这个场景,用户b先操作account_tbl表,用户a再操作stock_tbl表;用户b链接无论关闭还是未关闭,使用用户a的链接提交事务,会报错ORA-24774;但是反之,用户a链接无论关闭还是未关闭,使用用户b的链接提交事务,表现正常;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为在一阶段start之前,keepIfNecessary方法设置了this.shouldBeHeld = true,就一定会走这里的逻辑,那么现在的逻辑就是,所有数据库都会在一阶段hold链接,到二阶段结束才release链接,那感觉判断mysql8.0.29以下和maridb数据库是不是没啥意义了
这里不是到二阶段才release,是到了一阶段结束发现不需要holder时就会release掉连接
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里的提前holder时为了拿到连接后,进行commit前如果事务已经发生回滚了,可以提前阻断
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里是区分开了需要一阶段hold和二阶段hold的情况,一阶段hold的close时就释放了,二阶段hold的就不释放
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
rm-datasource/src/main/java/io/seata/rm/datasource/xa/ResourceManagerXA.java
Outdated
Show resolved
Hide resolved
return BRANCH_STATUS_CACHE.getIfPresent(xaBranchXid); | ||
} | ||
|
||
public static void remove(String xaBranchXid) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where call remove
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
并没有,只是为了留一个口子可以对里面的数据进行人工清理
Ⅰ. Describe what this PR did
1.分离BaseDataSourceResource,使只有xa需要的功能更加独立
2.修复同jdbcurl new多个datasource时,二阶段下发找不到被hold的connection,导致无法提交xa事务
3.BaseDataSourceResourcexa实现XADataSource,更加符合datasourcexa的定位
4.防悬挂处理需要判断datasource是否是需要hold连接的,比如oracle和mysql8.0.29及以上就不需要,keeper这块是静态的,只需要遍历一次即可,无需多个datasource都走一遍
5.防悬挂改为所有datasource都在start之前进行hold,这样就支持了所有支持xa的数据库防悬挂了,因为如果一开始不hold连接会会因为隔离性导致新的connection去rollback这个xa事务出现XAER_NOTA导致只能通过60次下发来兜底,当然针对不需要hold的库来说,只是为了防止xa star后下发二阶段指令的时候使用了另外的connection去rollback/commit,无法提前阻断事务的流转和事务的发现(XAER_NOTA),在一阶段connectionclose的时候如oracle这类数据库的connection会直接close掉
Ⅱ. Does this pull request fix one issue?
fixes #5494
fixes #4759
Ⅲ. Why don't you add test cases (unit test/integration test)?
Ⅳ. Describe how to verify it
Ⅴ. Special notes for reviews