Redis学习笔记4:Redis事务
Posted Vincent9847
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis学习笔记4:Redis事务相关的知识,希望对你有一定的参考价值。
事务:要么同时成功,要么同时失败。--->原子性
Redis事务:单条命令保证原子性,但其事务不保证。(即在整一个事务中,正确的命令依然执行,错误的不执行。)
1.正常开启Redis事务步骤:
- 开启事务(multi)
- 命令入队(。。。。。。)
- 执行事务(exec)
127.0.0.1:6379> multi #开启事务
ок
#命令入队
127.0.0.1:6379> set k1 v1 #设置值
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec #执行事务,此时所有命令才会被执行
1) ок
2) ок
3) "v2"
4) ок
2.放弃事务
127.0.0.1:6379> multi #开启事务
ок
127.0.0.1:6379> set kl v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> DISCARD #取消事务
оK
127.0.0.1:6379> get k4 #事务队列中命令都不会被执行!
(ni7)
3.编译型异常(代码编写错误),事务中所有的命令都不会执行。
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v1
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> exec #执行事务报错
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k4 #所有的命令都不会被执行
(nil)
4.运行时异常
如果事务队列中存在语法性错误,那么执行命令的时候,其他命令可以正常执行,作物命令抛出异常!
127.0.0.1:6379> set k1 v1 #设置值为字符串类型
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr k1 #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> get k3
QUEUED
127.0.0.1:6379> exec
#虽然第一条命令报错了,但是事务依旧正常执行成功了。
1) (error) ERR value is not an integer or out of range
2) OK
3) OK
4) "v3"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> get k3
"v3"
5.监控
正常执行成功:
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 #本金减20
QUEUED
127.0.0.1:6379> incrby out 20 #支出加20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
执行失败:(测试多线程修改值。使用watch可以当作redis的乐观锁操作!)
127.0.0.1:6379> watch money #监视money
оK
127.0.0.1:6379> multi
оK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec #执行之前,另外一个线程,修改了我们的值,这个时候,就会导致事务执行失败!
(nin)
失败后操作:
127.0.0.1:6379> UNWATCH #如果发现事务执行失败,就先解锁
ок
127.0.0.1:6379> WATCH money #获取最新的值,再次监视
оK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 1
QUEUED
127.0.0.1:6379> incrBY money 1
QUEUED
127.0.0.1:6379> exec #对比监视的值是否发生了变化,如果没有变化就执行成功,否则失败。
1) (integer) 99
2) (integer) 1
127.0.0.1:6379>
以上是关于Redis学习笔记4:Redis事务的主要内容,如果未能解决你的问题,请参考以下文章