分布式锁-基于数据库mysql实现

148 阅读2分钟

应用场景-幂等

伪代码
1.先读
2.后写


说明

先读,是为了解决幂等,即检验数据是否存在。不存在,写。

怎么确保原子问题?终极解决方案就是分布式锁。没有其他的解决方案。

优点就是,可以解决海量高并发场景的数据一致性的问题。

代价就是实现麻烦了一点。

最佳实践

能不用分布式锁,就不用分布式锁。99%的情况,都够用了。

除非是秒杀这种情况。即所有的用户访问同一个数据。

如果是支付业务里,不同的商家系统提交过来的请求数据重复的可能性很小,因为订单号包含了业务数据-商家号,单个商家根本没有那么大量的数据。一般每秒几百并发,还是没有任何问题的。就算万一数据重复,也没有关系,因为写数据的时候,有数据库的唯一索引约束,最终还是可以确保数据唯一性。

解决方案

实现分布式锁

悲观锁

伪代码

1.查询语句 for update
2.插入数据


缺点

粒度太大,因为大部分时候,都不会重复数据的情况。但是却把两条sql语句全部锁住了,导致其他线程不能写也不能读。

乐观锁

伪代码

1.读旧数据
2.修改语句 业务数据 version=version+1
where version=旧数据; //相等,成功1;不相等,失败0


问题
乐观锁的实现是更新账户金额,即更新数据。而不是新增数据。所以,只适合更新库存这样的应用场景。不适合新增数据。


解决方案
新增数据?分布式锁?基于redis set命令实现。

基于数据库和基于缓存的区别?

一个适合update。一个适合insert。