最近在项目中需要使用Spring Integration提供的基于JDBC实现的分布式锁。
在实践的过程中,我们遇到了一些有趣的问题,现在在此记录和总结一下。
一共遇到了两个问题,第一个和time to live有关,第二个还是和time to live有关。
第一个问题:由于time to live默认值不够长而导致被动失去锁的问题
sequenceDiagram
actor event_initiator
participant instance_1
participant instance_2
event_initiator->>instance_1: do something
note over instance_1: instance 1 获得了 lock
instance_1->>instance_1: start doing its thing
event_initiator->>instance_2: do another thing
note over instance_2: instance 2 等待 lock
note over instance_2: 等 ......
note over instance_2: 等 ......
note over instance_1: lock的超时时间TTL到,instance 1还没干完活,但是它失去了 lock<br>失去不同于主动release<br>失去lock后,instance 1还会继续干活<br>而这些活里面可能会有SQL写操作
note over instance_2: instance 2 获得了 lock
instance_2->>instance_2: start doing its thing
note over instance_1,instance_2: 此时二者同时干活,有撞车的风险,因为二者干活的先后顺序没有保证<br> instance 1尚未把它干完活后才能确定的状态写入DB,而instance 2已经开始干活了
note over event_initiator,instance_2: 为了降低风险,可以: <br> ① 想办法尽量让instance 1能在超时前干完活 <br> ② 以防万一可以考虑在合适的时间节点延长锁的过期时间
根据上图所示,我们有两个实例。