目录
1、何为事务机制?
Transaction(事务)是计算机的特有术语,它一般指单个逻辑工作单位,由一系列的操作组合而成,在这些操作执行的时候,要么都执行成功,要么都不执行,防止数据结果的不一致性。
简而言之,事务是一个不可分割的工作逻辑单位。为了衡量工作单元是否具备事务能力,需要满足四个特征:ACID,即 原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
- 原子性(Atomicity):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的数据必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- 实体完整性,存在唯一的主键
- 列完整性:字段类型、字段长度等符合所有的预设规则
- foreign key 外键约束
- 用户自定义完整性(如用户购物支付前后,商家收入和用户的余额总和不变)
- 隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- 持久性(Durability):事务处理结束后,对数据的修改就是永久的,会持久化到硬盘上,即便系统故障也不会丢失。
2、为什么需要使用事务
以支付场景为例,A向B支付100元,需要在A的账户中扣去100元,在B的账户中增加100元。这两个操作如果其中一个操作成功,另一个操作失败,就会导致问题。比如A付了钱B没有收到,或者A没付钱B收到了。我们可以使用事务将这两个操作变成一个原子性操作,要么一起成功,要么都不成功。
Redis的单个命令是原子性的(比如 get 、set、mget、mset),要么成功要么失败,不存在并发干扰的问题。
如果涉及到多个命令的时候,需要把多个命令作为一个不可分割的处理序列,就必须要依赖Redis的功能特性来实现了。
Redis提供了事务的功能,可以把一组命令一起执行。Redis的事务有3个特点:
- 按进入队列的顺序执行。
- 不会受到其他客户端的请求的影响。
- 事务不能嵌套,多个multi命令效果一样。
3、Redis模式下如何实现事务机制?
Redis的事务涉及到四个命令:multi(开启事务),exec(执行事务),discard(取消事务),watch(监视)。
- MULTI 开启事务,总是返回OK
- EXEC 提交事务
- DISCARD 放弃事务(即放弃提交执行)
- WATCH 监控
- QUEUED 命令加入执行的队列,没操作一个动作的时候,都先加入Queue
根据上述命令,Redis 事务的执行过程包含三个步骤:
- 开启事务:MULTI
- 命令入队:QUEUE
- 执行事务或丢弃:EXEC 或者 DISCARD
示例演示:fan和cai各有1000元,fan向cai转账100元。
127.0.0.1:6379> set fan 1000
OK
127.0.0.1:6379> set cai 1000
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby fan 100
QUEUED
127.0.0.1:6379> incrby c