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的乐观锁实践的更多相关文章

  1. 基于redis的分布式锁的分析与实践

    ​ 前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于 ...

  2. redis 乐观锁实践秒杀

    需求:有一个标(理解成抢红包也行,accountBalance预赋值1000元),大家可以抢购,每个用户抢购成功后,更新最后标的总数,在并发情况下,使用redis的乐观锁,保证更新标总值正确性,先往r ...

  3. 不用找了,基于 Redis 的分布式锁实战来了!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 作者:菜蚜 my.oschina.net/wnjustdoit/blog/1606215 前言:在分布式环境中,我们经常使用 ...

  4. 基于Redis的分布式锁真的安全吗?

    说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...

  5. 基于redis的分布式锁实现

    1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...

  6. [Redis] 基于redis的分布式锁

    前言分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁. 可靠性首先,为了确保 ...

  7. 基于redis的分布式锁实现方案--redisson

    实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill redis官方文档地址,请前往:http://www.redis.cn/topi ...

  8. 从零到一手写基于Redis的分布式锁框架

    1.分布式锁缘由 学习编程初期,我们做的诸如教务系统.成绩管理系统大多是单机架构,单机架构在处理并发的问题上一般是依赖于JDK内置的并发编程类库,如synchronize关键字.Lock类等.随着业务 ...

  9. 基于Redis的分布式锁到底安全吗(下)?

    2017-02-24 自从我写完这个话题的上半部分之后,就感觉头脑中出现了许多细小的声音,久久挥之不去.它们就像是在为了一些鸡毛蒜皮的小事而相互争吵个不停.的确,有关分布式的话题就是这样,琐碎异常,而 ...

随机推荐

  1. Python扩展库2—matplotlib

    1 载入matplotli的绘图模块,并重命名为plt import matplotlib.pyplot as plt 2 折线图 import matplotlib.pyplot as plt im ...

  2. Diamorphine rootkit的使用

    仅作LKM rootkit研究之用,滥用后果自负. 查看支持版本是否为2.6.x/3.x/4.x: uname -r 下载代码: git clone https://github.com/m0nad/ ...

  3. BUG_sql未解决bug

    [SQL]truncate table org_cert;受影响的行: 0时间: 0.021s [Err] 1055 - Expression #1 of ORDER BY clause is not ...

  4. 【Python】进程3

    #练习: import time from multiprocessing import Pool def run(fn): #fn: 函数参数是数据列表的一个元素 time.sleep(1) ret ...

  5. 【转载】 AI会议的总结(by南大周志华)

    原文地址: https://blog.csdn.net/LiFeitengup/article/details/8441054 最近在查找期刊会议级别的时候发现这篇博客,应该是2012年之前的内容,现 ...

  6. 模拟主库创建数据文件,dg备库空间不足时问题处理

    本篇文档测试目的: 模拟实际环境中,主库对表空间添加数据文件,备库空间不足,最终导致MRP进程自动断开,处理方式. 1.问题环境模拟 1)正常情况下的dg 主库创建数据文件,备库接受日志,自动创建表空 ...

  7. 12.2 关闭DLM 自动收集统计信息 (SCM0)ORA-00600之[ksliwat: bad wait time]

    一.报错日志 db_alert ORA-: ??????, ??: [ksliwat: bad wait time], [], [], [], [], [], [], [], [], [], [], ...

  8. 简易计算器的java实现

    伪代码 public class MainTestwei { 定义两个数组,List<Double> number和 List<Character>calculation分别用 ...

  9. xdoj 1067组合数学+动态规划 (一个题断断续续想了半年 233)

    题目分析 : (8 4) 可以由(7 4),(6,4),( 4,4) 基础上转化 意味着一个新加入的元素可以按照它加入的方式分类,从而实现动态规划 核心:加入方式 新加入的元素构成转换环的元素个数(n ...

  10. {python}完成完整的温度转换程序 猜数字游戏(猜价格,猜年龄等) 解析身份证号、学号不同片段的含义

    完成完整的温度转换程序 while True: a = int(input("如果是华氏转摄氏,请按1\n,如果是摄氏转华氏,请按2\n")) if a==1: h = float ...