应用场景-幂等
伪代码
1.先读
2.后写
说明
先读,是为了解决幂等,即检验数据是否存在。不存在,写。
怎么确保原子问题?终极解决方案就是分布式锁。没有其他的解决方案。
优点就是,可以解决海量高并发场景的数据一致性的问题。
代价就是实现麻烦了一点。
最佳实践
能不用分布式锁,就不用分布式锁。99%的情况,都够用了。
除非是秒杀这种情况。即所有的用户访问同一个数据。
如果是支付业务里,不同的商家系统提交过来的请求数据重复的可能性很小,因为订单号包含了业务数据-商家号,单个商家根本没有那么大量的数据。一般每秒几百并发,还是没有任何问题的。就算万一数据重复,也没有关系,因为写数据的时候,有数据库的唯一索引约束,最终还是可以确保数据唯一性。
解决方案
实现分布式锁
悲观锁
伪代码
1.查询语句 for update
2.插入数据
缺点
粒度太大,因为大部分时候,都不会重复数据的情况。但是却把两条sql语句全部锁住了,导致其他线程不能写也不能读。
乐观锁
伪代码
1.读旧数据
2.修改语句 业务数据 version=version+1
where version=旧数据; //相等,成功1;不相等,失败0
问题
乐观锁的实现是更新账户金额,即更新数据。而不是新增数据。所以,只适合更新库存这样的应用场景。不适合新增数据。
解决方案
新增数据?分布式锁?基于redis set命令实现。
基于数据库和基于缓存的区别?
一个适合update。一个适合insert。