Redis学习笔记:事务和锁
本文是自己的学习笔记,学习资料如下
B站狂神说Redis教程
1、事务
1.1、Redis事务的特性
Redis事务不保证一致性,本质是一组命令的集合。就是将一组命令放进一个队列里一条条执行,发生错误就触发错误处理机制,之前已经执行成功的命令也不会回退。同时也说明,事务可以保证一组命令能顺序执行。
1.2、redis事务开启的三个阶段
- 开启事务:
multi
。 - 命令入队:开始写命令,这里写的所有命令都是放入队列的操作,不执行。命令的执行只有执行事务时才会开始顺序执行。
- 取消事务:
discard
。如果取消了事务就不能执行事务,要重新开启事务。放弃了事务那事务里的命令就没有执行。 - 执行事务:
exec
。只有执行事务,命令才会被顺序执行,然后会顺序返回各命令的返回值。
1.3、redis事务中指令异常的处理方式
- 编译型异常:这种就是指令的语法错误。发生这种异常的时候,事务会被直接取消。下面是例子。
- 运行时异常:指令都没问题,但是运行时发生错误。这种异常不会影响事务,事务中其他正常的指令都会被执行。比如下面的例子,我们给一个字符串执行
incr
操作,使其发生错误,而事务中的其他指令也能被执行。
2、Redis实现乐观锁
- 悲观锁:很悲观,认为共有数据任何时候都会被修改,于是在共有数据的整个操作过程都会加上锁,哪怕这些操作过程中还包含其他操作,共有数据等会才会操作。我们熟知的
sychronized
就这悲观锁的代表,锁住的代码区域即使没有对共有数据操作,也不允许别人操作数据。这种锁很安全,但影响性能。 - 乐观锁:很乐观,相信整个过程数据不会被改动,只会在操作共有数据的时候才会去检查数据有没有被改动。常见的版本号version就是乐观锁的代表。这种锁安全性低一些,但是性能很高
Redis可以通过watch关键字来实现乐观锁。
2.1、watch关键字(乐观锁)
watch关键字的语法是watch key
,可以有多个key。表示对一个key进行监控(可以同时监控多个key),实际上可以理解成对这个key加上一个版本号记录。与此相反的unwatch
是放弃监视,放弃监视不能指定,只能放弃所有监视。
watch要和事务一起使用。当watch的作用就是监听一个key后,就会影响紧接着的一个事务。如果在这个事务执行之前,watch的key有过写入操作(版本号变化),那么这个事务就注定提交失败。
watch影响的只有紧接着watch语句的一个事务,后面的事务不会被watch影响。
下面是示例,左边的标签页会watch k1
执行事务,右边的标签页模拟一条新县城,在左标签页执行线程之前对k1
写入。然后左标签的事务执行失败,事务中的k3
没有存进去。
由上可以看出,Redis中watch关键字本身就具有乐观锁的性质,可以直接用watch实现乐观锁。