incubator-seata
incubator-seata copied to clipboard
分支事务回滚了,但是TM还是正常的提交
- [ ] I have searched the issues of this repository and believe that this is not a duplicate.
Ⅰ. Issue Description
分支 try{} catch(){} 了异常,返回正常。 可是 TM 提交了commit 代码 ConnectionProxy
@Override public void rollback() throws SQLException { targetConnection.rollback(); if (context.inGlobalTransaction()) { if (context.isBranchRegistered()) { report(false); } } context.reset(); }
并没有走到 report(false); 这块是不是可以优化一下
不是很明白您描述的意思 您是说 分支中异常被自行try catch后 应该走回滚路线么 不应该自行try catch 异常之后视为正常 而是应该视为异常 回滚整个全剧事物 如果是这样 那seata怎么知道异常被自行捕获了?
不是很明白您描述的意思 您是说 分支中异常被自行try catch后 应该走回滚路线么 不应该自行try catch 异常之后视为正常 而是应该视为异常 回滚整个全剧事物 如果是这样 那seata怎么知道异常被自行捕获了?
是这个意思。 因为代码执行到 rollback里了,可是没进入 report(false) 。 这样consumer端就要判断rpc的返回状态了(比如status=0业务正常,=-1 业务异常)。 server端代码还没看,我再了解下 report(false)有什么作用吧。
你这个和另外一个issue解决方式好像类似 可否先记录提交还是回滚的状态 在第二阶段tc通知的时候进行处理
你这个和另外一个issue解决方式好像类似 可否先记录提交还是回滚的状态 在第二阶段tc通知的时候进行处理
@Garlichead 两码事 1.这个rollback只有test case调用,业务执行时不可能进来 2.这个issue就是普通的把异常吃掉了,没通知到TM,了解下seata原理 3.这个issue可以用参与人回滚 https://github.com/seata/seata/pull/2101,不过参与人吃掉了异常,虽然最终数据没影响,但是tm会拿不到业务异常,只会抛出找不到全局事务的异常,不推荐吃掉异常
你这个和另外一个issue解决方式好像类似 可否先记录提交还是回滚的状态 在第二阶段tc通知的时候进行处理
@Garlichead 两码事
1.这个rollback只有test case调用,业务执行时不可能进来
2.这个issue就是普通的把异常吃掉了,没通知到TM,了解下seata原理
3.这个issue可以用参与人回滚 https://github.com/seata/seata/pull/2101,不过参与人吃掉了异常,虽然最终数据没影响,但是tm会拿不到业务异常,只会抛出找不到全局事务的异常,不推荐吃掉异常
1 rollback是seata层在第二阶段(完成阶段)发起决议完成后已经确定全局回滚才会执行rollback 这一点 我理解 业务层是不可能进来的 我想题主的想法想通过业务层去驱动rollback 只能是返回一个异常状态给seata 这样tm在发起决议的时候才知道需要全局回滚 是否可以自行try catch之后 执行完业务逻辑之后 throw一个异常 这样tm发起决议后 因为有分之抛出异常 就可以决议为全局回滚 2 您说的业务自行try catch了异常后 后续执行机制 个人查阅官方文档 应该是业务上报状态给tc 个人猜想tc会把状态存储在context中 以至于tm发起决议的时候可以知道各个分支事务的状态 3 您说的参与人吃掉了异常 数据没有影响 但是tm捕获不到业务异常 也就是可以理解tm是可以捕获到异常 但是异常被业务trycatch了 所以无法捕获业务异常 但是可以知道业务执行块里面发生了异常 这一点我不懂 因为异常在内部被捕获处理了 并没有throw tm如何知道内部发生了异常呢? 假如tm知道发生了分之异常 则要进行全局异常回滚 如果上游分之进行了本地事务提交 则需要进行回滚 也不会有其他分支脏数据 只是tm会认为这个异常默认是全局异常抛出 不利于异常抛出友好度 那反过来思考 分之代码块catch了exception 后 return true 是不是可以理解分之上报了执行正常给tc 这样tm发起决议的时候假设其他分支都是正常 那是不是认定为全局提交 而业务所需要的是全局回滚 这样就会导致其他分支的脏数据了
3.使用参与人回滚功能会提前让tc执行全局回滚,等到tm执行或者上报时跟tc通信会找不到这个全局事务或者状态不对,因此抛出异常. 目前决议是由tm决定并上报tc,参与方report并不影响结果,你们是希望由tc根据各个report来决议?
3.使用参与人回滚功能会提前让tc执行全局回滚,等到tm执行或者上报时跟tc通信会找不到这个全局事务或者状态不对,因此抛出异常.
目前决议是由tm决定并上报tc,参与方report并不影响结果,你们是希望由tc根据各个report来决议?
明白 参与人回滚功能我得去分析下 那这样参与人功能就满足题主的需求了 不是希望tc根据各个report进行决议 我查阅官方文档是分之report状态给tc tm发起决议 这里tm要根据xid和branchid去tc获取各个分之状态吧? 而参与人回滚功能tc已经执行了全局回滚了 所以xid就从context中销毁了 就找不到了出现xid cannot found exception 理解正常机制下全局提交和回滚是tm决议全局提交或回滚通知tc 然后tc再异步通知rm进行全局提交或回滚 那这里参与人回滚功能就不要经过tm 直接让tc异步通知所有rm执行全局回滚了
二阶段回滚是同步。 tc根据各个rm report结果决议二阶段行为我觉得可能需要,我跟小伙伴们讨论下。
有解决方案了吗?我现在也遇到了这个问题。如果我在controller层捕获了异常,我的这个分支事务会回滚,但是如果tm还是发起提交的话,其他子事务还是能提交掉。能不能在子分支事务抛出异常时,不管controller有没有捕获,都能够记录此子事务失败,全局需要回滚呢。
刚测试了一下,甚至controller抛出了异常,如果tm还是正常提交的话,最终还是会导致不一致。是我哪里有问题吗?不太理解
也就是说rm即使抛了异常,tc看起来就像毫不知情一样。tm发起提交就提交了
总体感觉就是tm想全局提交就全局提交,想全局回滚就全局回滚。其实并不会在意某个分支事务的成功与否。这是否会有问题呢?我还在思考。
undo_log从头到尾都没数据,回滚时控制台提示回滚成功,但是分支事务数据已经插入并没有回滚,哪位大佬知道,求告知
undo_log从头到尾都没数据,回滚时控制台提示回滚成功,但是分支事务数据已经插入并没有回滚,哪位大佬知道,求告知
我也遇到了这个问题,请问一下有解决吗
我是把版本又重新确认了一遍,应该是版本不对应,spring boot 和spring cloud alibaba和seata的版本,得去官网查对应关系
---原始邮件--- 发件人: @.> 发送时间: 2022年6月28日(周二) 晚上10:11 收件人: @.>; 抄送: @.@.>; 主题: Re: [seata/seata] 分支事务回滚了,但是TM还是正常的提交 (#2515)
undo_log从头到尾都没数据,回滚时控制台提示回滚成功,但是分支事务数据已经插入并没有回滚,哪位大佬知道,求告知
我也遇到了这个问题,请问一下有解决吗
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>