事务简介
redis事务就是一个命令执行队列,将一系列预定义命令包装成一个整体(一个队列)。当执行时,一次性按照添加顺序,依次执行,中间不会被打断或干扰。
一个队列中,一次性,顺序性,排他性的执行一系列命令。
事务的基本操作
事务的边界
- 开启事务
multi
# 设定事务的开始位置,此指令执行后,后面的所有指令都加入到事务中
- 执行事务
exec
# 设定事务的结束位置,同时执行事务,与multi成对出现,成对使用
当输入multi命令后,后面的指令输入结束,按回车,不在返回执行命令结束的返回结果,而是返回QUEUED。
- 取消事务
discard
# 终止当前事务的定义,发生在multi后,exec前
当discard命令执行后,在想执行exec命令,就会报错(without multi)
事务的工作流程
注意事项
- 语法错误
- 处理结果:整体事务中所有命令均不执行,出现这样的情况相当于执行了discard命令,也就是说,后面要想在执行exec命令,是不行的。
- 处理结果:整体事务中所有命令均不执行,出现这样的情况相当于执行了discard命令,也就是说,后面要想在执行exec命令,是不行的。
- 运行错误:指令格式正确,但是无法正确执行,如对listi进行incr操作
- 处理结果:能正确执行的命令会执行,运行错误的命令不会执行
- 处理结果:能正确执行的命令会执行,运行错误的命令不会执行
注意:已经执行完毕的命令对应的数据不会自动回滚,需要程序员自己在代码中实现数据回滚
手动进行事务回滚
- 记录操作过程中被影响的数据之前的状态
- 单数据:string
- 多数据:hash,list,set,zset
- 设置指令恢复所有的被修改项
- 单数据:直接set(注意周边属性,如时效性)
- 多数据:修改对应值,或整体克隆复制
基于特定条件的事务执行----锁
- 对key添加监视锁,在执行exec之前如果key发生了变化,终止事务执行
watch key1 key2 ...
# watch监控的key,不一定是要在事务中用到。
# 在exec命令之前,如果监控的key发生了变化,则执行exec返回nil
- 取消对所有key的监视
unwatch
watch不能定义在事务中,unwatch定义在事务中
基于特定条件的事务----分布式锁
- 利用setnx设置一个公共锁
setnx lock-key value
# 利用setnx的返回值特征,有值则返回设置失败,无值则返回成功
# 对于返回设置成功的,拥有控制权,进行下一步具体业务操作
# 对于返回设置失败的,不具有控制权,排队或等待
- 通过del释放锁
死锁的解决办法
- 使用expire为锁key添加时间限定,到期不释放则,自动放弃锁
expire lock-key second
pexpire lock-key milliseconds