1.分布式锁是保证任一时刻只有一个线程持有锁。

1.1 mysql数据库实现

create table dss_lock {id,lock_name,lock_status,start_time,expire_time};

优势:数据库可以保证高可用。

   设置expire_time可以避免一个线程获取锁后出现异常后,锁一直占用。

劣势:线程执行时间超长问题。到expire_time后仍然没有执行完成。解决:在应用中自己去判断前一个任务是否还在执行,如果是就不再执行,如job,将运行日志插入job_log表,在job中每次查询是否有在运行中的该job。需要继续执行需要手动线下调整,否则也无意义。

   任务调度实例重启任务捞取的开始时间。应该以expire_time开始,即上一次结束时间,如果当前时间小于expire_time

      执行端多实例。解决直接封装成api,调用时直接调用网关通过注册中心负载

1.2 redis实现

redisTemplate.opsForValue().setIfAbsent("dsslock",111,3, TimeUnit.MINUTES);
优势:缓存数据库性能有保障。
   保证可用性AP.
劣势:在集群模式下极端情况下会有数据一致性问题(redis RedLock)。当一个master挂掉后,slave拉起的过程中,锁信息没有同步,导致第二个线程也持有锁。解决,采用redssion或者保障最终一致性,即,1.1任务超长的解决方案。


2 并发更新


CAScompare and set
更新库存或扣费,0时不能操作

乐观锁:update store_amount=
(store_amount-#{amount}) where
store_amount >#{amount}
and store_amount=#{before_amount}

悲观锁:
select for update ;
update store_amount=(store_amount-#{amount}) where for update
commit;




posted on 2020-05-13 15:31  pu20065226  阅读(158)  评论(0编辑  收藏  举报