博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于redis的乐观锁实践
阅读量:5031 次
发布时间:2019-06-12

本文共 2337 字,大约阅读时间需要 7 分钟。

edis真是一个分布式应用场景下的好东西,对于我们的应用设计,功劳大大的!

 

今天要研究的是基于redis的事务机制以及watch指令(CAS)实现乐观锁的过程。

所谓乐观锁,就是利用版本号比较机制,只是在读数据的时候,将读到的数据的版本号一起读出来,当对数据的操作结束后,准备写数据的时候,再进行一次数据版本号的比较,若版本号没有变化,即认为数据是一致的,没有更改,可以直接写入,若版本号有变化,则认为数据被更新,不能写入,防止脏写。

 

下面,看看如何基于redis实现乐观锁。

 

首先,看看redis的事务,涉及到的指令,主要有multi,exec,discard。而实现乐观锁的指令,在事务基础上,主要是watch指令,以及unwatch指令,unwatch通常可以不用!

 

案例1:redis的纯事务

下面是ssh窗口1里面的操作:

127.0.0.1:6379> set hello 1OK127.0.0.1:6379> get hello"1"127.0.0.1:6379> multiOK127.0.0.1:6379> incr helloQUEUED127.0.0.1:6379> incr hello                 #这一步执行完毕后,去另外一个窗口(ssh窗口2),对hello这个key做incr操作,将hello对应的值变成2。完成后,继续后面的exec指令QUEUED127.0.0.1:6379> exec1) (integer) 3                             #注意,这时hello的值是3了,前面执行get hello指令时,值是1哟,说明这个值在其他地方被修改过,这里的其他地方,就是指前面提到的,在另外一个连接窗口里面执行的。2) (integer) 4127.0.0.1:6379>

这个情景下,multi和exec之间的指令,依然是可以执行的。

 

下面的操作,就是在ssh窗口2里面的操作:

127.0.0.1:6379> 127.0.0.1:6379> get hello"1"127.0.0.1:6379> incr hello(integer) 2127.0.0.1:6379>

 

案例2: 利用watch指令,基于CAS机制,简单的乐观锁

下面是ssh窗口1里面的操作:

127.0.0.1:6379> watch helloOK127.0.0.1:6379> get hello"4"127.0.0.1:6379> multiOK127.0.0.1:6379> incr helloQUEUED127.0.0.1:6379> incr hello                #这一步执行完毕后,去另外一个窗口(ssh窗口2),对hello这个key做incr操作,将其值变成5。完成后,继续后面的exec指令QUEUED127.0.0.1:6379> exec(nil)                                     #注意,这是exec执行后返回的是nil,表示事务提交执行失败127.0.0.1:6379> 127.0.0.1:6379> get hello                 #这个时候,查看hello对应的值,就是在另外一个窗口(ssh窗口2)执行incr后的值"5"

 

下面是ssh窗口2里面的操作:

127.0.0.1:6379> incr hello(integer) 5127.0.0.1:6379>

 

案例3:watch指令在一次事务执行完毕后,即结束其生命周期

下面是ssh窗口1里面的操作:

127.0.0.1:6379> multi                     #接着上面案例2后,不再输入watch hello这个指令,直接启动事务OK127.0.0.1:6379> incr helloQUEUED127.0.0.1:6379> incr hello                #这一步执行完毕后,就在另外一个窗口(ssh窗口2),执行incr hello,将hello的值变成6。QUEUED127.0.0.1:6379> exec                      #另外一个窗口(ssh窗口2)里面的操作结束后,继续来这个窗口执行该指令,依然完成了上面的两个incr hello的操作。1) (integer) 72) (integer) 8127.0.0.1:6379>

 

下面是ssh窗口2里面的操作:

127.0.0.1:6379> incr hello(integer) 6127.0.0.1:6379>

 

上述3个案例的操作,指令其实非常的少,两个窗口的指令全集,截图如下:

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

 

通过这个简单的例子,基于redis的乐观锁,可以得出一个结论:

1. 乐观锁的实现,必须基于WATCH,然后利用redis的事务。

2. WATCH生命周期,只是和事务关联的,一个事务执行完毕,相应的watch的生命周期即结束。

转载:https://www.baidu.com/link?url=lMo3SLlWGSMxGT_nv64y6EYr-p35uOr-8Vp4dtEURh7GSexKS11wLm53hZ-4Omnp9snWHPr0jAGrWU-b5LYYHa&wd=&eqid=f3667c5000056736000000055a66979c

转载于:https://www.cnblogs.com/qq1069284034/p/8334449.html

你可能感兴趣的文章
16.RDD实战
查看>>
MainFrame知识小结(20120210)—dfsort/syncsort中的数据类型
查看>>
jsp题库 (一)小测(25/21)
查看>>
D - Flip tile
查看>>
Java连接RabbitMQ之创建连接
查看>>
开户vim编程之--cscope支持
查看>>
python数据类型图解
查看>>
js获取标准北京时间
查看>>
DZ!NT论坛 3.6.711删除用户各种错解决方案
查看>>
C#微信登录-手机网站APP应用
查看>>
HTML5实践 -- iPhone Safari Viewport Scaling Bug
查看>>
一位数据挖掘成功人士 给 数据挖掘在读研究生 的建议
查看>>
Python3.6.0安装
查看>>
hdu1049
查看>>
H5项目常见问题及注意事项
查看>>
索尼(SONY) SVE1512S7C 把WIN8降成WIN7图文教程
查看>>
时间模块 && time datetime
查看>>
jquery自动生成二维码
查看>>
spring回滚数据
查看>>
新浪分享API应用的开发
查看>>