tx-lcn icon indicating copy to clipboard operation
tx-lcn copied to clipboard

[5.0.2] LCN TM 通知 TC 失败导致数据不一致

Open coolbeevip opened this issue 3 years ago • 17 comments

1. Bug Description

我的业务是 A,B,C三个服务,A 服务作为业务入口,依次调用 B,C 两个服务。

USER -> A A -> B A -> C

当TM 通知 B 或者 C commit 的前,如果这两个服务宕机,此时 A 服务并没有捕获到异常。这会导致 USER 已为接口调用成功了。

我不确定是我的用法有问题,还是目前就存在这样的问题。我理解此时用该有一定的重试机制,并且重试失败后此全局事务应该处于挂起状态,并抛出异常给业务。

2. Environment:

  • JDK version: 1.8
  • OS: macOS
  • TX-LCN version: 5.0.2

coolbeevip avatar Mar 16 '21 01:03 coolbeevip

你好 解决了吗?

chenhh23 avatar Apr 29 '21 09:04 chenhh23

有自己添加重试机制吗?还是怎么处理的?

chenhh23 avatar Apr 29 '21 09:04 chenhh23

TM 通知 B 或者 C 失败后吞没了异常,我改成了抛出异常给 A。让业务侧感知到这个问题。此时导致事务不一致是不可避免的。这时就需要人工干预了

coolbeevip avatar Apr 29 '21 09:04 coolbeevip

你直接吞吐异常的话 也是可以人工干预的啊

chenhh23 avatar Apr 29 '21 11:04 chenhh23

感觉是不是可以在tc端单独起个线程,如果有通知失败的情况 直接把之前的提交给回滚

chenhh23 avatar Apr 29 '21 11:04 chenhh23

感觉是不是可以在tc端单独起个线程,如果有通知失败的情况 直接把之前的提交给回滚

都提交了,怎么回滚?

coolbeevip avatar Apr 29 '21 11:04 coolbeevip

定义一个回滚的接口 具体代码根据业务了

chenhh23 avatar Apr 29 '21 13:04 chenhh23

人工干预也是一样的吧? 要么提交要么回滚

chenhh23 avatar Apr 29 '21 13:04 chenhh23

我感觉这里的关键问题当出现提交或者回滚失败的时候要让 A 服务知道。目前主干版本 A 是不知道通知失败的。因为 TM 吞没了异常。由于这不是柔性事务,我觉得即使重试也不适合太长时间和次数,因为这会导致锁表的时间过长。

总之,我觉得让事务发起方 A 知道失败就可以了,这样业务系统使用者就能感知到出现了数据不一致的异常。然后人为去处理就行了

coolbeevip avatar Apr 29 '21 14:04 coolbeevip

定义一个回滚的接口 具体代码根据业务了

如果回滚还需要接口,那么还不如直接用基于 SAGA 模式的柔性事务实现

coolbeevip avatar Apr 29 '21 14:04 coolbeevip

我感觉这里的关键问题当出现提交或者回滚失败的时候要让 A 服务知道。目前主干版本 A 是不知道通知失败的。因为 TM 吞没了异常。由于这不是柔性事务,我觉得即使重试也不适合太长时间和次数,因为这会导致锁表的时间过长。

总之,我觉得让事务发起方 A 知道失败就可以了,这样业务系统使用者就能感知到出现了数据不一致的异常。然后人为去处理就行了 A知道了也是人工处理 但看那个aspectLog也是一样的人工处理啊

chenhh23 avatar Apr 29 '21 14:04 chenhh23

定义一个回滚的接口 具体代码根据业务了

如果回滚还需要接口,那么还不如直接用基于 SAGA 模式的柔性事务实现

这个只是针对失败场景的处理啊 正常情况或者是基本大部分情况还是走的原来的流程啊

chenhh23 avatar Apr 29 '21 14:04 chenhh23

按照流程图 image 只有“5.响应通知事务组”异常才会有数据不一致的问题,因为B,C异常,事务协调器(T)是能感知的,并且会告知A。

Jasonfory avatar May 06 '21 04:05 Jasonfory

按照流程图 image 只有“5.响应通知事务组”异常才会有数据不一致的问题,因为B,C异常,事务协调器(T)是能感知的,并且会告知A。

怎么告知?

chenhh23 avatar May 07 '21 06:05 chenhh23

按照流程图 image 只有“5.响应通知事务组”异常才会有数据不一致的问题,因为B,C异常,事务协调器(T)是能感知的,并且会告知A。

遗憾的是,实际的实现与这个图有一些差异,当 commit[1] 或 rollback[2] 后时如果出现 RPC 通信异常,那么此处并不会抛出异常

[1] https://github.com/codingapi/tx-lcn/blob/26a429557dc4be1e22a24c61b450286827efe398/txlcn-tm/src/main/java/com/codingapi/txlcn/tm/txmsg/transaction/NotifyGroupExecuteService.java#L71

[2] https://github.com/codingapi/tx-lcn/blob/26a429557dc4be1e22a24c61b450286827efe398/txlcn-tm/src/main/java/com/codingapi/txlcn/tm/txmsg/transaction/NotifyGroupExecuteService.java#L73

coolbeevip avatar May 07 '21 06:05 coolbeevip

看这个https://github.com/codingapi/tx-lcn/issues/8 发起方的TC会通知TM补偿事务

Jasonfory avatar May 07 '21 09:05 Jasonfory

看这个#8 发起方的TC会通知TM补偿事务

由于RPC 通讯异常,补偿失败时,全局事务的业务发起方无法收到异常,因为异常被 TM 吞没了

coolbeevip avatar May 08 '21 02:05 coolbeevip