【Redis】redis事物与管道

Redis 事务(Transaction)

事务概念

  • 事务:是一组操作的集合,是不可分割的工作单元。
  • Redis 事务特点:
    • 一个事务可以一次执行多个命令。
    • 所有命令都被顺序化,形成一个队列。
    • 所有命令在执行 EXEC 时一次性、顺序执行。

与 MySQL 事务的区别

特点 Redis MySQL
提交前执行情况 命令只入队,执行 EXEC 前不实际执行 执行前可能已部分生效
原子性保障 不保证所有指令成功或失败(无回滚) 支持回滚
执行过程 命令顺序执行,期间不被其它命令插入 依赖事务隔离级别

Redis 保证事务内命令顺序执行:
1 -> 2 -> 3,不会变成 1 -> 2 -> 被插队 -> 3


事务使用示例

1. 正常事务执行

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 1
QUEUED
127.0.0.1:6379(TX)> set k2 2
QUEUED
127.0.0.1:6379(TX)> set k3 3
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK
2) OK
3) OK

2. 放弃事务

127.0.0.1:6379> MULTI
127.0.0.1:6379(TX)> set k1 11
127.0.0.1:6379(TX)> set k2 22
127.0.0.1:6379(TX)> DISCARD
OK

事务出错

1. 语法错误

在命令入队阶段就报错,事务无法执行:

127.0.0.1:6379> MULTI
127.0.0.1:6379(TX)> set k2
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> EXEC
(error) EXECABORT Transaction discarded because of previous errors.

2. 逻辑错误

命令入队成功,但某条命令在执行时失败,不影响其他命令:

127.0.0.1:6379> set name luobozi
127.0.0.1:6379> MULTI
127.0.0.1:6379(TX)> INCR name   # name 是字符串,不能自增
127.0.0.1:6379(TX)> set k1 12
127.0.0.1:6379(TX)> EXEC
1) (error) ERR value is not an integer
2) OK

Redis 锁机制:乐观锁

Watch 命令

  • 使用 WATCH 对某个 key 进行监控。
  • 如果事务执行前该 key 被修改,EXEC 执行失败,事务不会生效。

下面演示了Watch 对num施加了乐观锁,最后EXEC提交前修改了num导致事务失败
【Redis】redis事物与管道_第1张图片

乐观锁 vs 悲观锁

类型 描述
乐观锁 假设不会发生冲突,提交前检查(如 Redis WATCH
悲观锁 假设总会冲突,使用互斥锁机制控制访问

Redis 管道(Pipeline)

原因

  • TCP 通信频繁读写会造成性能瓶颈。
  • 多次发送命令、等待响应效率低。

管道原理

  • 一次性发送多条命令 到 Redis。
  • Redis 执行完后 一次性返回结果
  • 不具有事务的隔离和原子性。

使用示例

# test.txt 文件内容:
get k1
set k2 v2
set k3 v3

# 使用管道批量执行
cat test.txt | redis-cli -a 123456 --pipe

注意:

  • 管道命令执行失败,不会影响后续命令执行。
  • 命令过多会导致客户端阻塞过久。

事务 VS 管道

特性 事务(Transaction) 管道(Pipeline)
原子性 有部分原子性,顺序执行,不可插队 无原子性
并发控制 会阻塞其它命令插入(顺序执行) 不阻塞其他命令
发送方式 多条命令逐条发送,最后 EXEC 执行 多条命令一次性发送
执行方式 统一入队后执行 服务端逐条执行后统一返回
错误处理 语法错误直接终止事务 失败命令不影响后续命令

你可能感兴趣的:(redis,数据库,缓存)