比如 A 发起事务,先调用 A > B1.fun1,再调用 A > B2.fun1,其中B1和B2是相同模块不同实例,fun1是同一个方法,如果在最后事务通知阶段,B1或者B2出现通知失败会导致产生如下的补偿信息:
{
"address": "192.168.1.161:60010",
"className": "com.xxx.xxx.user.service.demo.DemoService",
"currentTime": 1516777802788,
"data": "C5IBK2NvbS55b3VuYS55eHoudXNlci5zZXJ2aWNlLmRlbW8uRGVtb1NlcnZpY2UMEgZ0eFRlc3QbehBqYXZhLmxhbmcuT2JqZWN0GAAQARwjeg9qYXZhLmxhbmcuQ2xhc3MYABABJCpAcHVibGljIHZvaWQgY29tLnlvdW5hLnl4ei51c2VyLnNlcnZpY2UuZGVtby5EZW1vU2VydmljZS50eFRlc3QoKQ==",
"groupId": "zqIGXYkf",
"methodStr": "public void com.xxx.xxx.user.service.demo.DemoService.txTest()",
"model": "A",
"startError": 0,
"state": 0,
"time": 5117,
"txGroup": {
"groupId": "zqIGXYkf",
"hasOver": 1,
"isCommit": 0,
"list": [
{
"address": "192.168.1.161:49296",
"isCommit": 0,
"isGroup": 0,
"kid": "dux2oC5M",
"methodStr": "public com.xxx.xxx.common.domain.demo.Demo com.xxx.xxx.edge.service.demo.DemoService.save(com.youna.yxz.common.domain.demo.Demo)",
"model": "B",
"modelIpAddress": "192.168.1.161:62003",
"modelName": "/192.168.1.161:9183",
"notify": 0,
"uniqueKey": "8fa2f86e1f37be77c669d6383f0a488b"
},
{
"address": "192.168.1.161:49296",
"isCommit": 0,
"isGroup": 0,
"kid": "yRgeaVSg",
"methodStr": "public com.xxx.xxx.common.domain.demo.Demo com.xxx.xxx.edge.service.demo.DemoService.save(com.youna.yxz.common.domain.demo.Demo)",
"model": "B",
"modelIpAddress": "192.168.1.161:62000",
"modelName": "/192.168.1.161:8114",
"notify": 1,
"uniqueKey": "3eab2f2d491f0f4f3e05fa03270114be"
}
],
"nowTime": 0,
"rollback": 0,
"startTime": 1516777797675,
"state": 1
},
"uniqueKey": "70000381435434571fa98e58c5e694f4"
}
注意里面的list列表为上述的B模块,如果存在这种多个B模块相同方法,则最后出现的那个B模块实例对象的 notify 如果为 1,则在调用补偿时,全部B模块都会被rollback,反之都会被commit。
推测,我没看TxManager的源码,这个bug估计是TxManager补偿时,是通过一个map来遍历的补偿信息,key可能为model + methodStr,之前B模块不同实例的key估计是被后出现的覆盖了。