-
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
同一个PreparedStatement执行多次execute会报ShouldNeverHappenException #7100
Comments
不提供异常信息如何排查? |
mybatis-plus调用报错 |
connection.setAutoCommit(false) 如果不设置为false,那么一次dml都需要注册分支,而这个connection已经被上一次动作注册过分支了。 |
这个我能理解,但针对mybatis-plus的场景,方法加了@GlobalTransactional,是否应该包含@transactional的所有功能呢,要不然使用分布式事务两个注解都需要加 |
@GlobalTransactional的作用是管理分布式事务,而@transactional是用户自行选择,并且@transactional是属于spring的,@GlobalTransactional属于seata,seata不应该去限制用户使用connection的行为。而是按照jdbc规范,当autocommit为true,那么每次execute都应该提交对应的事务,根据分布式xa来说,这个xa事务就已经完成,需要一个新的connection来完成该动作。(当然在不使用xa来说,这个动作是可以完成的)或许应该在这种场景上将xa的TMJOIN功能使用上 |
感谢解答!xa的TMJOIN功能后续有计划使用上吗?因为在不使用xa情况下,connection自动提交事务下statement是支持被执行多次的 |
我理解就是在connection已经存在branchid的情况下并且autocommit是true,说明这个connection是被复用的继续执行sql了,理论上应该在这种情况下不去创建新的分支(因为如果xaBranchXid不为空,说明这个连接没有close,属于还在使用阶段),然后利用原本的xaBranchXid,startxa时flag为TMJOIN |
不过我记得之前oracle那边会默认隐式join,如果一个事务已经进入了prepare阶段,貌似是join不了的,如果是这样,可能需要将事务的prepare纳入到close阶段,而不是commit阶段 |
这块不用担心,只要将prepare挪到在close阶段中进行,connectionproxyxa只是包装了xa的逻辑,底层的connection逻辑如何理论上不需要太过担心,只要准守jdbc规范即可。connectionproxyxa的close只是为了清除上下文等行为。 |
prepare需要挪到在ConnectionProxyXA.xaCommit阶段执行前,因为close在xaCommit之后,prepare放在close,执行xaCommit会报错,我不知道挪到xaCommit有什么其他影响,目前我测试是没问题的 |
提交pr吧,我整体review下 |
钉钉号发我[email protected]邮箱,我拉你进贡献者群中 |
Ⅰ. Issue Description
报错方法在io.seata.rm.BaseDataSourceResource.hold(String, T),产生来源为mybatis-plus使用com.baomidou.mybatisplus.extension.service.IService.updateBatchById(Collection)对象存在不同更新属性时,会有多个PreparedStatement,有@GlobalTransactional同时也加入@transactional注解就不会报错。
伪代码如下,把手动提交事务打开就没问题,同上面使用mybatis-plus加入@transactional时,调用io.seata.rm.datasource.xa.ExecuteTemplateXA.execute(AbstractConnectionProxyXA, StatementCallback<T, S>, S, Object...)方法就不会执行connectionProxyXA.setAutoCommit(false);
`@Resource
private DataSource dataSource;
Ⅱ. Describe what happened
If there is an exception, please attach the exception trace:
Ⅲ. Describe what you expected to happen
Ⅳ. How to reproduce it (as minimally and precisely as possible)
Minimal yet complete reproducer code (or URL to code):
Ⅴ. Anything else we need to know?
Ⅵ. Environment:
java -version
):uname -a
):The text was updated successfully, but these errors were encountered: