天天看点

redis事务与乐观锁

文章目录

    • 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的操作

redis事务与乐观锁
redis事务与乐观锁

unwatch:取消所有key的监控