Redis.事务


事务

  • 概述
  • 错误处理
  • WATCH命令

概述

Redis事务是指将多条命令加入队列,一次批量执行多条命令,每条命令会按顺序执行,事务执行过程中不会受客户端传入的命令请求影响。
事务同命令一样都是Redis的最小执行单位,要么全执行,要么全不执行。

Redis事务的相关命令如下:

MULTI标识一个事务的开启
EXEC执行事务中的所有命令
DISCARD放弃事务
WATCH监视Key改变
UNWATCH放弃监视

张三给李四转账500,两个终端,一个演示事务,一个查询余额

[root@localhost ~]# redis-cli -p 6377
127.0.0.1:6377> set user_zs_mount 1000
OK
127.0.0.1:6377> set user_ls_mount 10000
OK
127.0.0.1:6377> MULTI
OK
127.0.0.1:6377(TX)> DECRBY user_zs_mount 500
QUEUED
127.0.0.1:6377(TX)> INCRBY user_ls_mount 500
QUEUED
127.0.0.1:6377(TX)> EXEC

1) (integer) 500
2) (integer) 10500
   127.0.0.1:6377> 
[root@localhost ~]# redis-cli -p 6377

# 未EXEC执行事务之前查询
127.0.0.1:6377> get user_zs_mount    
> 1000
127.0.0.1:6377> get user_ls_mount    
> 10000

# EXEC执行了事务之后查询
127.0.0.1:6377> get user_zs_mount    
> 500                                 
127.0.0.1:6377> get user_ls_mount    
> 10500                               

当事务开启时,事务期间的命令并没有立即执行,而是加入队列,只有执行EXEC命令时,事务中的命令才会按照顺序依次执行,从而事务间就不会导致数据脏读、不可重复读、幻读的问题,也就没有隔离级别。

错误处理

  • 语法错误:
127.0.0.1:6377> MULTI
OK
127.0.0.1:6377(TX)> INCRBY user_zs_mount 500
QUEUED
127.0.0.1:6377(TX)> DECRBY user_ls_mount
(error) ERR wrong number of arguments for 'decrby' command
127.0.0.1:6377(TX)> EXEC                                           
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6377> get user_zs_mount                                  
> 500
127.0.0.1:6377> get user_ls_mount                                  
> 10500

事务中只要有一个命令有语法错误,执行EXEC命令后Redis就会直接返回错误,正确的命令也不会执行。

  • 运行错误:
127.0.0.1:6377> MULTI
OK
127.0.0.1:6377(TX)> INCRBY user_zs_mount 500
QUEUED
127.0.0.1:6377(TX)> DECRBY user_ls_mount aa
QUEUED
127.0.0.1:6377(TX)> EXEC
  1) (integer) 1000
  2) (error) ERR value is not an integer or out of range

127.0.0.1:6377> get user_zs_mount
   > 1000
127.0.0.1:6377> get user_ls_mount
   > 10500

运行错误是在命令执行时才出现的错误,这种错误在实际执行之前Redis无法发现,如果事务中出现了运行错误,事务里其它的命令依然会继续执行,包括出错之后的命令。

Redis的事务不支持回滚

Redis官网解释:

  • 语法错误是编程导致的错误,应该在开发过程中解决
  • 不用支持回滚功能,Redis内部简单化,而且还比较快
  • 在事务命令入队过程中,发现相关命令逻辑使用错误,可以进行放弃该事务
  • 如果使用错误的Redis命令,且没有放弃事务,最终也会导致事务整体执行失败

WATCH命令

WATCH通过监视指定Redis Key,一旦其中一个值发生改变(被修改或删除),之后的事务就不会执行。

127.0.0.1:6377> get user_ls_mount
> 10500> 
127.0.0.1:6377> WATCH user_ls_mount
OK
127.0.0.1:6377> INCRBY user_ls_mount 50
(integer) 10550
127.0.0.1:6377> MULTI
OK
127.0.0.1:6377(TX)> INCRBY user_ls_mount 500
QUEUED
127.0.0.1:6377(TX)> EXEC
(nil)
127.0.0.1:6377> get user_ls_mount
> 10550 

WATCH取消监视:

  • 事务执行之后,不管是否执行成功还好是失败,都会取消对应的监视
  • 当监视的客户端断开连接时
  • UNWATCH命令取消所有Key的监视

声明:Rock 版权所有,内容均为原创,欢迎转载。

转载:转载请注明原文链接 - Redis.事务


我是一个程序员,致力于网页开发,我还很年轻,什么也不懂。