简介
事务的概念很简单,在一些场景下,我们需要执行一系列sql语句,那么我们必须保证这一系列语句要么全部执行,要么一条都不执行。这就是事务
事务的4个特性-ACID
先通过一张图来理解事务的四大特性都是用来解决什么问题的,然后我们再去理解四大特性的概念。
以A向B转账100元为例,将转账简化为一下3个步骤
- A账户减去100元
- 查询B账户余额为100元
- 将B账户余额设置为200元
我们基于下图看在转账过程中可能出现的问题与4大特性如何对应
ACID定义
解决问题 | 定义 | 示例 | |
---|---|---|---|
Consistency(一致性) | 事务的最终目标 | 在事务开始之前和事务结束以后,数据库的完整性没有被破坏 | A向B转账,数据库最后只有两种结果:1是A账户少100,B账户多100;2是A,B账户金额不变 |
Atomic(原子性) | sql语句执行到一半,系统故障 | 一个事务中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节 | 当执行步骤2时,系统异常。数据库会通过undo log进行回滚 |
Duration(持久性) | 当事务提交,还未写入磁盘时,系统故障 | 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失 | 当事务commit之后,系统异常。数据库会通过redo log恢复事务 |
Isolation(隔离性) | 多个事务并发修改或查询同一条数据导致数据不一致 | 数据库允许多个并发事务同时对其数据进行读写和修改的能力 | 当执行完步骤2后,另一个事务将B的余额设置为了300元,而当前事务会将B的余额再设置为200元。那么另一个事务的操作就被覆盖了。隔离性通过隔离级别解决多事务并发问题 |
隔离性
多事务并发可能产生的问题
问题 | 定义 | 举例 |
---|---|---|
脏读 | A事务对一行数据修改,还未提交,B事务便来读取此行数据,并且读到了数据 | 事务1: A有1000元,B有100元,A向B转账100元。 当A账户减少100元之后, 事务2来查询A账户的余额,只有900元,查询B账户只有100元。 |
不可重复读 | A事务在读取了某些数据后,再次读取这些数据,发现这些数据被修改了 | 事务1: A有1000元,B有100元,A向B转账100元。事务2:查询B的余额,并登记,登记后校验登记是否有误。 1. 事务2先查询B的余额为100元,做登记操作 2. 此时事务1完成,将B的账户设为200元 3. 校验登记金额与账户余额是否一致,查询B的余额为200,登记金额为100,出错! |
幻读 | 一个事务内按照相同的查询条件查询以前的数据,发现数据总量变了 | 事务1: A要给群里所有好友每人转账100元。事务2: B添加好友到了群里 1. 事务1查询群里好友有10人,确定人员和转账金额,开始转账 2. 事务2添加了1名好友到群里,并提交事务 3. A转账完成后,查询好友是否收到转账,再次查询群里好友,发现有11人,此时就不知道转账是否正确执行了! |
隔离级别
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
read uncommitted(没有提交,别的事务也可以查询) | 0 | 0 | 0 |
read committed(只有事务提交后才能查询) | 1 | 0 | 0 |
repeatable read(在事务开始查询的值,哪怕其他事务修改后,该事务仍查询到以前的值) | 1 | 1 | 0 |
serializable(事务开始时,其他事务不能做任何更新操作) | 1 | 1 | 1 |
参考: