事务
事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,就全部不成功,同一个事务的操作具备同步优点
START TRANSACTION; | BEGIN;
···
····
ROLLBACK;
COMMIT;
START TRANSACTION | BEGIN: 开启事务(处于事务中,不会影响数据库数据)
ROLLBACK: 回滚事务(取消事务,前提是事务未提交前回滚)
COMMIT : 事务提交(事务生效后会立即影响数据库数据)
事务ACID特性
原子性(Atomicity)
指事务是一个不可分割的工作单位,事务中的操作要么执行成功,要么执行失败
一致性(Consistency)
事务前后数据的完整性必须保持一致(数据库的完整性:如果数据库在某个时间点下,所有的数据都符合所有的约束,则称数据库为符合完整性的状态)
隔离性(Isolation)
指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离
持久性(Durability)
指一个事务一旦被提交,数据库中的数据改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
事务安全问题
脏读: 两事务 某一事务读取到另一个事务修改且未提交的数据
不可重复读: 某一事务多次读取同一条记录的过程,读取的结果不相同过程数据有更改,读取到另一个事务已经提交的数据
虚读(幻读): 某一事务多次查询数据,由于其他事务 新增 或 删除 记录造成多次查询出的记录条数不同
事务隔离级别
防止不同隔离性的问题
隔离类型 | 脏读 | 不可重复读 | 幻读 |
未提交 READ UNCOMMITTED | 允许 | 允许 | 允许 |
已读提交 READ COMMITTED | 禁止 | 允许 | 允许 |
可重复读 REPEATABLE READ | 禁止 | 禁止 | 可能 |
顺序读 SERIALIZABLE | 禁止 | 禁止 | 禁止 |
一般默认 可重复读 REPEATABLE READ 、 已读提交 READ COMMITTED
修改隔离级别
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL 隔离类型;
SESSION: 当前会话
GLOBAL: 全局
查询隔离级别
SELECT @@TX_ISOLATION; (MySQL版本8前)
SELECT @@TRANSACTION_ISOLATION;
未提交 (READ UNCOMMITTED)
读未提交,该隔离级别允许脏读取,其隔离级别是最低的
时间(T) | 事务A (存) | 事务B(取) |
T1 | 开始事务 | 开始事务 |
T2 | == | 查余额(500元) |
T3 | == | 取300元 |
T4 | 查余额(200元) | == |
T5 | == | 滚动事务 |
T6 | 存800元 | == |
T7 | 提交事务 | == |
T8 | 取100元 | |
T9 | 提提交事务 |
最后余额剩1200元。T4 A脏读B修改的数据,T5 B回滚(撤回T5前的所有操作),最后B只提取100元!
已读提交 (READ COMMITTED)
读已提交是不同的事务执行的时候只能获取到已经提交的数据
时间(T) | 事务A (存) | 事务B(取) |
T1 | 开始事务 | 开始事务 |
T2 | == | 查余额(500元) |
T3 | 查余额(500元) | == |
T4 | == | 取500元 |
T5 | 查余额(500元) | == |
T6 | == | 提交事务 |
T7 | 查余额(0) | |
T8 | 提交事务 |
A只能读取 事务提交后的数据!!
可重复读 (REPEATABLE READ)
保证在事务处理过程中,多次读取同一个数据时,该数据的值和事务开始时刻是一致的
时间(T) | 事务A | 事务B |
T1 | 开始事务 | |
T2 | 查所有数据 | 开始事务 |
T3 | == | 插入一条数据 |
T4 | == | 提交事务 |
T5 | 查所有数据 | |
T6 | 修改范围数据 | |
T7 | 查所有数据! | |
T8 | 提交事务 |
事务A 的 T3 查询数据 与 T5查询数据 是一样的 ,数据无误后 对整表数据值修改,紧接查询事务多出了一条数据!!(A 没有对新增数据进行更改,则不会显示,除非事务提交)
顺序读 (SERIALIZABLE)
最严格的事务隔离级别。事务以排队形式进行执行。某一事务对数据进行修改必须等另一个 提交 或 回滚 ,才可以进行数据修改!!
隔离级别锁的情况
读未提交(RU): 有行级的锁,没有间隙锁。与RC的区别是能够查询到未提交的数据
读已提交(RC): 有行级的锁,没有间隙锁,读不到没有提交的数据
可重复读(RR): 有行级的锁,有间隙锁,每读取的数据都一样,且没有幻读的情况
序列化(S): 有行级锁,也有间隙锁,读表的时候,就已经上锁了