因为存在多客户端并发,所以必须保证操作的原子性。比如银行卡扣款问题,获取余额,判断,扣款,写回就必须构成事务,否则就可能出错。
在传统单体应用单机部署的情况下,可以使用Java并发相关的锁,如ReentrantLcok或synchronized进行互斥控制。但是,随着业务发展的需要,原单体单机部署的系统,渐渐的被部署在多机器多JVM上同时提供服务,这使得原单机部署情况下的并发控制锁策略失效了,为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题。(推荐学习:Redis视频教程)
分布式锁的实现条件
1、互斥性,和单体应用一样,要保证任意时刻,只能有一个客户端持有锁
2、可靠性,要保证系统的稳定性,不能产生死锁
3、一致性,要保证锁只能由加锁人解锁,不能产生A的加锁被B用户解锁的情况
Redis实现分布式锁不同的人可能有不同的实现逻辑。
分布式环境下,数据一致性问题一直是一个比较重要的话题,而又不同于单进程的情况。分布式与单机情况下最大的不同在于其不是多线程而是多进程。多线程由于可以共享堆内存,因此可以简单的采取内存作为标记存储位置。而进程之间甚至可能都不在同一台物理机上,因此需要将标记存储在一个所有进程都能看到的地方。
常见的是秒杀场景,订单服务部署了多个实例。如秒杀商品有4个,第一个用户购买3个,第二个用户购买2个,理想状态下第一个用户能购买成功,第二个用户提示购买失败,反之亦可。而实际可能出现的情况是,两个用户都得到库存为4,第一个用户买到了3个,更新库存之前,第二个用户下了2个商品的订单,更新库存为2,导致出错。
常见的锁方案如下:
基于数据库实现分布式锁
基于缓存,实现分布式锁,如redis
基于Zookeeper实现分布式锁
更多Redis相关技术文章,请访问Redis数据库使用入门教程栏目进行学习!