事务
- 概述
- 错误处理
- 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的监视
Comments | NOTHING
该文章已经关闭评论