并发冲突解决方案(DB/缓存)

一、版本号解决冲突
对表增加版本号,每次更新,进行版本号比较,相同则更新,并且版本号+1,否则更新失败。避免多线程查出这条数据后,同时间对这一条数据进行操作,造成数据覆盖(即ABA覆盖的问题)
更新失败,让发起方重新发起

二、表中冗余锁字段
在表中增加两个字段,例如锁业务流水号,锁时间【避免表锁,一定要命中索引,转为行锁】
1、当多个发起方调用接口准备更新同一条数据的时候
2、加锁,封装为LockUtil【该逻辑与redis分布式锁逻辑差不多,只是操作对象不一样,一个缓存一个DB】
lock
在一个事务中,通过forupdate查这条数据,判断锁业务流水号,锁时间是否为空
如果为空,则说明这条数据可操作,为锁业务流水号,锁时间赋值,更新记录,并返回true
如果不为空,则说明这条数据已被其他发起方占用了,比较锁业务流水号与发起方的流水号是否一致,一致则为重入,返回true,不一致,则判断锁时间是否过期(限定时间范围),过期则进行抢占,为锁业务流水号,锁时间赋值,更新记录,并返回true,否则返回false
3、根据lock返回,进行相关的业务操作
4、解锁,封装为LockUtil【finally解锁】
在一个事务中,通过forupdate查这条数据,判断锁业务流水号,锁时间是否为空
如果为空,打error日志告警
如果不为空,比较锁业务流水号与发起方的流水号是否一致,一致则将锁业务流水号,锁时间更新为空,否则打error日志告警

三、记录锁
新建一张表,用于存储各种业务锁,操作过程与二差不多。只是落到专属的记录表中(自定义粗细粒度锁,以及各个场景汇总)
如果是先初始化好锁记录,可有专属的配置信息存于表中。例如xxx锁,失效时间,是否可重入等

四、事务控制
直接通过事务控制,将整个操作逻辑都包在事务中,相当于悲观锁了,这样可能会引发长事务,或者死锁

五、redis分布式锁
使用redis做分布式锁,目前市面上提供了redisson,已封装好逻辑,不需要自己实现,具体百度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值