情景一:
客户端超时时间(CT)小于服务端超时时间(ST)。【调整时间大小】
当客户端调用服务端向数据库发起请求时,假如是个大数据量提交,
假如客户端超时时间为10s,服务端超时时间为15s
当提交等待时间为12s时,客户端已经返回错误,而服务端未超时。
最后12s后服务端提交成功。而客户端返回失败。
情景二:
1、分布式锁超时时间小于业务超时时间【调整时间大小】
2、数据库里相关字段没有唯一索引【增加唯一幂等性验证】
那么如果线程A提交的数据出现问题(如大数据提交等),处于等待状态,并获得分布式锁。
而线程B、C...也来提交,由于分布式锁,访问被拦截。
当分布式锁超时时间结束时,线程Z刚好提交。
如果数据库缺少唯一性索引,此时线程A与线程Z可能同时提交成功。
情景三:
1、分布式锁超时时间小于业务超时时间【调整时间大小】
2、业务有重试机制
3、数据库里相关字段没有唯一索引【增加唯一幂等性验证】
(1)由于数据库连接数被占满,流水 1 创建的事务处于等待提交状态。
(2)系统 A 发现交易失败,重试次数不满 8 次的,立即发起重试,触发生成流水
2 的请求。
(3)5s 以内数据均被分布式锁拦截,无法提交。
(4)经过 5s 后,系统 B 的分布式锁失效,此时事务仍在等待未提交。
(5)6s 时,流水 2 成功越过数据库查询幂等校验发起事务,此时流水 1 拿到数
据库连接,流水 1 和 2 两个事务同时提交。
(6)由于数据库未做唯一索引,且支付受理模块打穿下层幂等原则,生成 2 个
TXID,导致两事务同时提交成功。
(7)收益结转重复记账,用户多了一笔收入。
得出一个结论:分布式锁在以下条件同时满足的情况下并发控制会被打穿。
(1)上层业务系统层面有重试机制。
(2)业务请求存在一定时间之后提交成功的情况,例如本例中第一次请求在事务
等待 6s 后获得了数据库链接,提交数据库成功。
(3)下游系统缺乏其他有效的幂等控制手段
原文地址:https://www.cnblogs.com/churao/p/8494244.html