基于redis的乐观锁实践
redis真是一个分布式应用场景下的好东西,对于我们的应用设计,功劳大大的!
今天要研究的是基于redis的事务机制以及watch指令(CAS)实现乐观锁的过程。
所谓乐观锁,就是利用版本号比较机制,只是在读数据的时候,将读到的数据的版本号一起读出来,当对数据的操作结束后,准备写数据的时候,再进行一次数据版本号的比较,若版本号没有变化,即认为数据是一致的,没有更改,可以直接写入,若版本号有变化,则认为数据被更新,不能写入,防止脏写。
下面,看看如何基于redis实现乐观锁。
首先,看看redis的事务,涉及到的指令,主要有multi,exec,discard。而实现乐观锁的指令,在事务基础上,主要是watch指令,以及unwatch指令,unwatch通常可以不用!
案例1:redis的纯事务
下面是ssh窗口1里面的操作:
127.0.0.1:> set hello
OK
127.0.0.1:> get hello
""
127.0.0.1:> multi
OK
127.0.0.1:> incr hello
QUEUED
127.0.0.1:> incr hello #这一步执行完毕后,去另外一个窗口(ssh窗口2),对hello这个key做incr操作,将hello对应的值变成2。完成后,继续后面的exec指令
QUEUED
127.0.0.1:> exec
) (integer) #注意,这时hello的值是3了,前面执行get hello指令时,值是1哟,说明这个值在其他地方被修改过,这里的其他地方,就是指前面提到的,在另外一个连接窗口里面执行的。
) (integer)
127.0.0.1:>
这个情景下,multi和exec之间的指令,依然是可以执行的。
下面的操作,就是在ssh窗口2里面的操作:
127.0.0.1:>
127.0.0.1:> get hello
""
127.0.0.1:> incr hello
(integer)
127.0.0.1:>
案例2: 利用watch指令,基于CAS机制,简单的乐观锁
下面是ssh窗口1里面的操作:
127.0.0.1:> watch hello
OK
127.0.0.1:> get hello
""
127.0.0.1:> multi
OK
127.0.0.1:> incr hello
QUEUED
127.0.0.1:> incr hello #这一步执行完毕后,去另外一个窗口(ssh窗口2),对hello这个key做incr操作,将其值变成5。完成后,继续后面的exec指令
QUEUED
127.0.0.1:> exec
(nil) #注意,这是exec执行后返回的是nil,表示事务提交执行失败
127.0.0.1:>
127.0.0.1:> get hello #这个时候,查看hello对应的值,就是在另外一个窗口(ssh窗口2)执行incr后的值
""
下面是ssh窗口2里面的操作:
127.0.0.1:> incr hello
(integer)
127.0.0.1:>
案例3:watch指令在一次事务执行完毕后,即结束其生命周期
下面是ssh窗口1里面的操作:
127.0.0.1:> multi #接着上面案例2后,不再输入watch hello这个指令,直接启动事务
OK
127.0.0.1:> incr hello
QUEUED
127.0.0.1:> incr hello #这一步执行完毕后,就在另外一个窗口(ssh窗口2),执行incr hello,将hello的值变成6。
QUEUED
127.0.0.1:> exec #另外一个窗口(ssh窗口2)里面的操作结束后,继续来这个窗口执行该指令,依然完成了上面的两个incr hello的操作。
) (integer)
) (integer)
127.0.0.1:>
下面是ssh窗口2里面的操作:
127.0.0.1:> incr hello
(integer)
127.0.0.1:>
上述3个案例的操作,指令其实非常的少,两个窗口的指令全集,截图如下:

在另外一个窗口(ssh窗口2)中的操作:

通过这个简单的例子,基于redis的乐观锁,可以得出一个结论:
1. 乐观锁的实现,必须基于WATCH,然后利用redis的事务。
2. WATCH生命周期,只是和事务关联的,一个事务执行完毕,相应的watch的生命周期即结束。
基于redis的乐观锁实践的更多相关文章
- 基于redis的分布式锁的分析与实践
		
 前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于 ...
 - redis 乐观锁实践秒杀
		
需求:有一个标(理解成抢红包也行,accountBalance预赋值1000元),大家可以抢购,每个用户抢购成功后,更新最后标的总数,在并发情况下,使用redis的乐观锁,保证更新标总值正确性,先往r ...
 - 不用找了,基于 Redis 的分布式锁实战来了!
		
Java技术栈 www.javastack.cn 优秀的Java技术公众号 作者:菜蚜 my.oschina.net/wnjustdoit/blog/1606215 前言:在分布式环境中,我们经常使用 ...
 - 基于Redis的分布式锁真的安全吗?
		
说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...
 - 基于redis的分布式锁实现
		
1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...
 - [Redis] 基于redis的分布式锁
		
前言分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁. 可靠性首先,为了确保 ...
 - 基于redis的分布式锁实现方案--redisson
		
实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill redis官方文档地址,请前往:http://www.redis.cn/topi ...
 - 从零到一手写基于Redis的分布式锁框架
		
1.分布式锁缘由 学习编程初期,我们做的诸如教务系统.成绩管理系统大多是单机架构,单机架构在处理并发的问题上一般是依赖于JDK内置的并发编程类库,如synchronize关键字.Lock类等.随着业务 ...
 - 基于Redis的分布式锁到底安全吗(下)?
		
2017-02-24 自从我写完这个话题的上半部分之后,就感觉头脑中出现了许多细小的声音,久久挥之不去.它们就像是在为了一些鸡毛蒜皮的小事而相互争吵个不停.的确,有关分布式的话题就是这样,琐碎异常,而 ...
 
随机推荐
- springboot区分开发、测试、生产多环境的应用配置
			
转:https://blog.csdn.net/daguairen/article/details/79236885 springboot区分开发.测试.生产多环境的应用配置(一) Spring可使用 ...
 - 【Python】socket编程-2
			
#练习3:TCP协议+while循环 服务端: import socket #socket模块 import sys reload(sys) sys.setdefaultencoding(" ...
 - 【git学习笔记】
			
一.查看git的配置文件 1.在项目下,有一个.git的隐藏文件 2.config为git的配置文件 3.查看config :branch表示分支,此配置文件表示当前有两个分支NNU和master,一 ...
 - SpringBatch Sample (三)(XML文件操作)
			
前篇关于Spring Batch的文章,讲述了Spring Batch 对CSV文件的读写操作. 本文将通过一个完整的实例,与大家一起讨论运用Spring Batch对XML文件的读写操作.实例流程是 ...
 - [转]熵(Entropy),交叉熵(Cross-Entropy),KL-松散度(KL Divergence)
			
https://www.cnblogs.com/silent-stranger/p/7987708.html 1.介绍: 当我们开发一个分类模型的时候,我们的目标是把输入映射到预测的概率上,当我们训练 ...
 - 2.14 加载Firefox配置
			
2.14 加载Firefox配置(略,已在2.1.8讲过,请查阅2.1.8节课) 回到顶部 2.14-1 加载Chrome配置 一.加载Chrome配置chrome加载配置方法,只需改下面一个地方,u ...
 - sharpkeys键盘按键重映射
			
/********************************************************************** * sharpkeys键盘按键重映射 * 说明: * 键 ...
 - python调用caffe环境配置
			
背景是这样的,项目需要,必须将训练的模型通过C++进行调用,所以必须使用caffe或者mxnet,而caffe是用C++实现,所以有时候简单的加载一张图片然后再进行预测十分不方便 用caffe写pro ...
 - servlet简单介绍
			
什么是Servlet? servlet是一种Java编程语言类,用于扩展托管通过请求 - 响应编程模型访问的应用程序的服务器的功能.尽管servlet可以响应任何类型的请求,但它们通常用于扩展Web服 ...
 - C语言--第三周作业评分和总结(5班)
			
作业链接:https://edu.cnblogs.com/campus/hljkj/CS2017-5/homework/1073 一.评分要求 要求1 完成PTA第三周所有题(20分). 要求2 4道 ...