文章目录
-
- redis事务的特性
- 事务的基本操作
- 举例证明redis的事务泛原子性
- watch及乐观锁的操作
redis事务的特性
redis事务的本质其实就是一组redis命令的集合,其特点如下
- redis事务是一个泛原子操作(ps:某些情况redis的事务不是原子性的,比如多条命令中有一条命令属于运行时异常,那么该异常不会影响其他命令的执行)
- redis事务没有隔离级别的概念,因为redis是单线程的,每个事务都是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
- redis中的单条命令存在原子性
-
redis中的事务为间接执行,执行过程
multi:事务开启,标记下面输入的redis命令会按顺序加入到可执行队列中。
…:入队列的命令
exec :事务执行,
discard:放弃该事务
事务的基本操作
127.0.0.1:6379> multi --开启事务
OK
127.0.0.1:6379(TX)> set k1 v1 --添加执行命令进入队列
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> exec --执行事务
1) OK
2) OK
3) OK
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
#########################################################
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k4 v
QUEUED
127.0.0.1:6379(TX)> set k5 v5
QUEUED
127.0.0.1:6379(TX)> set k6 v6
QUEUED
127.0.0.1:6379(TX)> discard --执行事务
OK
127.0.0.1:6379> get k5 --可以看到,事务并没有执行
(nil)
127.0.0.1:6379> get k6
(nil)
举例证明redis的事务泛原子性
###############################运行时异常
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k7 str
QUEUED
127.0.0.1:6379(TX)> incr k7 --字符串不可以进行自增操作,属于运行时异常
QUEUED
127.0.0.1:6379(TX)> set k8 1
QUEUED
127.0.0.1:6379(TX)> incr k8
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) ERR value is not an integer or out of range --可以看到第二条命令报错
3) OK
4) (integer) 2
127.0.0.1:6379> mget k7 k8 --可以看到,虽然第二条命令报错了,但没有影响其它的命令
1) "str"
2) "2"
127.0.0.1:6379>
########################################################
--编译时异常
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> sett k9 1 --添加无法编译的命令,会直接报错
(error) ERR unknown command `sett`, with args beginning with: `k9`, `1`,
127.0.0.1:6379(TX)> set k10 1
QUEUED
127.0.0.1:6379(TX)> set k11 1
QUEUED
127.0.0.1:6379(TX)> exec --由于事务中存在编译时异常,所以整个事务不执行
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> mget k10 k11 --可以看到事务并没有执行
1) (nil)
2) (nil)
watch及乐观锁的操作
watch用于监听一个对象是否改变,常与事务配合使用,以便达到乐观锁的作用。
-
乐观锁:认为任何情况下都不会出现并发问题,所以在操作的时候不增加锁,只有在任务具体执行的写操作时候,才会与需要改变的数据进行version对比,如果一致任务才会执行成功。
(ps:原理在建立任务的时候会记录当前需要被改变对象的version,而任何时候只要对象被改变那么该对象的version也会改变)
- 悲观锁:认为任何情况下都会出现并发问题,所以在操作的时候都会增加锁,来保证数据的准确性。(ps:效率较低)
代码验证
执行exec之前先执行了,改变money的操作
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL1kkaOl3YE9UeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL5cjMzIDMxcTMyEzNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
unwatch:取消所有key的监控