Skip to content
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

Open
wants to merge 53 commits into
base: develop
Choose a base branch
from

Conversation

funky-eyes
Copy link
Contributor

@funky-eyes funky-eyes commented Oct 28, 2022

  • I have registered the PR changes.

Ⅰ. 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

@codecov-commenter
Copy link

codecov-commenter commented Jan 17, 2023

Codecov Report

Merging #5034 (bf8832e) into develop (0710c64) will increase coverage by 0.00%.
The diff coverage is 39.06%.

Additional details and impacted files

Impacted file tree graph

@@            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     
Files Coverage Δ
.../main/java/io/seata/rm/BaseDataSourceResource.java 39.47% <100.00%> (+4.62%) ⬆️
...ta/rm/datasource/xa/AbstractConnectionProxyXA.java 12.19% <100.00%> (ø)
...ta/rm/datasource/xa/AbstractDataSourceProxyXA.java 6.25% <100.00%> (ø)
...eata/rm/datasource/xa/DataSourceProxyXANative.java 66.66% <40.00%> (-5.56%) ⬇️
...a/io/seata/rm/datasource/xa/DataSourceProxyXA.java 68.75% <33.33%> (-4.59%) ⬇️
...a/io/seata/rm/datasource/xa/ConnectionProxyXA.java 56.86% <58.33%> (+0.36%) ⬆️
...a/io/seata/rm/datasource/xa/ResourceManagerXA.java 20.28% <12.50%> (-0.61%) ⬇️
...ata/rm/datasource/xa/BaseDataSourceResourceXA.java 28.57% <28.57%> (ø)

... and 4 files with indirect coverage changes

@funky-eyes
Copy link
Contributor Author

@slievrly This pr need you to help me review

@funky-eyes funky-eyes added mode: XA XA transaction mode module/rm-datasource rm-datasource module type: bug Category issues or prs related to bug. labels Apr 6, 2023
@PeppaO
Copy link
Contributor

PeppaO commented Apr 6, 2023

1.如果所有都在start时,hold链接,那判断oracle和mysql8.0.29以下等需要hold的链接是不是可以去掉了
2.类里面静态Keeper使用后,会有性能问题吗
3.存在oracle 同库同用户场景,如果在二阶段下发分支提交/回滚时,原有连接意外close,通过resourceId获取数据源获取到同用户的链接,在提交分支事务上是否存在异常

@funky-eyes
Copy link
Contributor Author

1.如果所有都在start时,hold链接,那判断oracle和mysql8.0.29以下等需要hold的链接是不是可以去掉了 2.类里面静态Keeper使用后,会有性能问题吗 3.存在oracle 同库同用户场景,如果在二阶段下发分支提交/回滚时,原有连接意外close,通过resourceId获取数据源获取到同用户的链接,在提交分支事务上是否存在异常

1.只在8.0.29以上及其他mysql,mariadb以外的数据库都会在一阶段close,释放holder
2.理论上不至于有性能问题,就是个map,性能影响微乎其微,跟数据库的io比可以忽略不计
3.不存在,只要prepare后的事务,原链接意外close后(仅mysql mariadb),其他的链接可以commit/rollback,而其他的数据库而言一阶段prepare后,就会close链接(这个close是归还连接池,上面说的意外close是disconnect)

return;
if (isHeld()) {
if (shouldBeHeld()) {
// if kept by a keeper, just hold the connection.
Copy link
Contributor

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数据库是不是没啥意义了

Copy link
Contributor

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的链接提交事务,表现正常;

Copy link
Contributor Author

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掉连接

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的提前holder时为了拿到连接后,进行commit前如果事务已经发生回滚了,可以提前阻断

Copy link
Contributor Author

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的就不释放

Copy link
Contributor

@PeppaO PeppaO left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

return BRANCH_STATUS_CACHE.getIfPresent(xaBranchXid);
}

public static void remove(String xaBranchXid) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where call remove ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

并没有,只是为了留一个口子可以对里面的数据进行人工清理

@funky-eyes funky-eyes added this to the 1.8.1 milestone Nov 3, 2023
@funky-eyes funky-eyes requested a review from slievrly December 1, 2023 02:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mode: XA XA transaction mode module/rm-datasource rm-datasource module type: bug Category issues or prs related to bug.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

XA模式下Mysql版本多数据源差异资源悬挂问题 xa模式事务无法提交
6 participants