一、事务1、redis事务本质一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!Redis 单条命令是保证原子性的,但是Redis事务不保证原子性Redis 事务没有隔离级别的概念!所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行!Execredis的事务执行顺序:1、开启事务( multi )2、命令入队( )3、执行事务( exec )2、测试案例正常执行事务> multi # 开启事务OK=
摘要由CSDN通过智能技术生成
一、事务
1、redis事务本质
一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!
Redis 单条命令是保证原子性的,但是Redis事务不保证原子性
Redis 事务没有隔离级别的概念!
所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行!Exec
redis的事务执行顺序: 1、开启事务( multi ) 2、命令入队( ) 3、执行事务( exec )
2、测试案例
正常执行事务
> multi # 开启事务
OK
===== 命令入队 =====
> set k1 v2
QUEUED
> set k2 v2
QUEUED
> get k2
QUEUED
===== 执行事务 =====
> exec # 执行事务,按照入队顺序一步一步执行,执行一次之后事务就结束了,如果需要重新执行事务需要重新开启,命令入队操作
OK
OK
v2
取消事务
127.0.0.1:6379> multi #开启事务
OK
===== 命令入队 =====
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
===== 取消事务 =====
127.0.0.1:6379> discard #取消事务后之前队内所有的命令都不会被执行了
OK
127.0.0.1:6379> get k2
(nil)
127.0.0.1:6379> multi # 开启事务
OK
127.0.0.1:6379> set k1 "v1" #设置字符串值
QUEUED
127.0.0.1:6379> incr k1 #字符串值自增,会报错
QUEUED
127.0.0.1:6379> set k2 v2 #接着执行
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range #字符串不是整形不能自增,有异常!但是不影响其他事务!
3) OK
4) OK
127.0.0.1:6379> get k2 #依旧可以获取到值
"v2"
编译型异常(命令有错!),事务中所有的命令都不会被执行!
127.0.0.1:6379> multi #开启事务
OK
=====命令入队 =====
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> getset k3
(error) ERR wrong number of arguments for 'getset' command #这里因为命令有错,但是不会中断事务,所以下面可以继续写
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> set k5 v5
QUEUED
127.0.0.1:6379> exec #执行事务
(error) EXECABORT Transaction discarded because of previous errors. #执行事务报错,所有的命令都不会被执行
127.0.0.1:6379> get k5 #获取值为nil
(nil)
3、watch(监视)
悲观锁: 1、很悲观,认为什么时候都会出问题,无论做什么都会加锁!
乐观锁 1、很乐观,认为什么时候都不会出问题,所以不会上锁,更新数据的时候去判断一下,在此期间是否有人修改这过个数据 2、获取 version 3、更新的时候比较 version
锁测试 正常执行成功的情况
127.0.0.1:6379> set money 100 #设置零花钱为100
OK
127.0.0.1:6379> set out 0 #设置已经花出去的钱为0
OK
127.0.0.1:6379> watch money #监视money,事务执行成功之后,监控会自动取消
OK
127.0.0.1:6379> multi #开启事务,事务正常结束,数据期间没有发生变动,这个时候就正常执行成功
OK
===== 命令入队 =====
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec #执行事务
1) (integer) 80
2) (integer) 20