redis 事务

redis 事务与 MySQL 事务的区别和联系

redis 的事务和 MySQL 的事务在概念上是类似的, 都是把一系列的操作绑定成一组, 能够让这一组操作批量执行.

首先来讲一下 MySQL 事务的四大特性:

  1. 原子性: 把多个操作打包成一个整体, 事务中的所有操作要么全都执行成功, 要么全都失败回滚, 不能只执行其中一部分操作.
  2. 一致性: 运行事务前后的数据结果都是合理有效的, 不会出现非法的中间状态.
  3. 隔离性: 事务并发执行过程中, 每个事务对其它事务操作都是透明的, 一个事务的中间结果对其它事务是不可见的. 隔离性可以避免并发执行之间产生的脏读, 幻读, 不可重复读等问题.
  4. 持久性: 事务中做出的修改都存在硬盘中.

然而, redis 的事务和 MySQL 的事务还是有一定区别的:

  1. 弱化的原子性: redis 并没有实现回滚的机制, 只能做到将事务中的所有操作批量执行, 并不能做到中间执行失败就回到初始状态.
  2. 不保证一致性: redis 并没有回滚机制, 所以事务中的数据可能会有执行失败的场景, 并不能保证结果的数据是合理有效的.
  3. 不涉及隔离性: redis 是单线程处理请求的, 并不会涉及到多线程环境下出现的问题.
  4. 不具备持久性: redis 是将数据存入内存中的, 虽然 redis 有持久化机制, 但是持久化机制是 redis-server 来完成的, 与事务无关.
  • 所以, redis 事务存在的最主要的意义是为了将操作打包在一起执行, 避免其它客户端的命令插到中间. 为了实现这一点, redis 引入了一个队列(每一个客户端都会有一个), 开启事务的时候, 此时客户端输入的命令会发送给服务器并且进入这个队列, 当遇到了执行事务的命令的时候, 就会把这个队列中的任务都按照顺序依次执行.

redis 事务操作

  1. MULTI: 开启一个事务, 成功返回 OK.
127.0.0.1:6379> multi
OK
  1. EXEC: 执行事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set key1 111
QUEUED
127.0.0.1:6379> set key2 222
QUEUED
127.0.0.1:6379> set key3 333
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) OK
127.0.0.1:6379>

每次添加一个操作的时候, 都会提示 “QUQUQD”, 说明这个操作已经进入到客户端的队列中了, 真正执行 exec 的时候, 客户端才会把上述的操作发送给服务器, 服务器根据这个队列中的操作依次执行.

  1. DISCARD: 放弃当前的事务, 清空客户端的事务队列, 之前的操作不会被执行到.
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set key1 111
QUEUED
127.0.0.1:6379> set key2 222
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get key1
(nil)
127.0.0.1:6379> get key2
(nil)
127.0.0.1:6379> 
  1. WATCH: 在该客户端上监控一组具体的 key, 当开启了事务操作了一个 key, 但是还未执行事务的时候该 key 被其它客户端修改了, 此时再执行事务就会执行失败.
# 客户端 1
127.0.0.1:6379> watch key1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set key1 111
QUEUED
127.0.0.1:6379> set key2 222
QUEUED

# 此时事务还未提交, 但是客户端 2 执行如下操作
127.0.0.1:6379> set key1 222
OK

# 此时客户端 1 再执行事务
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get key1
"222"
127.0.0.1:6379> get key2
(nil)
127.0.0.1:6379> 
  1. UNWATCH: 取消对 key 的监控, 相当于 WATCH 的逆操作.
WATCH 的实现原理

redis 服务器中每个 key 都会有一个版本号, 这个版本号是一个简单的整数, 每次修改都会使版本号变大, 服务器来维护每个 key 的版本号.

当用户执行 WATCH 命令的时候, 这组被执行的 key 在该客户端中会被监控. 在真正提交事务的时候, 会判定当前这个 key 的版本号与当初 WATCH 的时候的版本号是否一致, 如果不一致, 说明这个 key 在其它客户端中被修改过了, 此时就直接丢弃事务中的操作.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值