6. 事务
把多条语句作为一个整体进行操作的功能,被称为数据库事务。
1. ACID特性⚓
- A:atomicity,原子性,将所有SQL作为原子工作单元执行,要么全部执行,要么全部不执行;
- C:consistency,一致性,事务完成后,所有数据的状态都是一致的,即A账户只要减去了100,B账户则必定加上了100;
- I:isolation,隔离性,如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离;
- D:durability,持久性,即事务完成后,对数据库数据的修改被持久化存储。
对于单条SQL语句,数据库系统自动将其作为一个事务执行,这种事务被称为隐式事务
。
要手动把多条SQL语句作为一个事务执行,使用BEGIN
开启一个事务,使用COMMIT
提交一个事务,这种事务被称为显式事务
。
BEGIN;
<SQL>;
COMMIT;
有些时候,我们希望主动让事务失败,这时,可以用ROLLBACK
回滚事务,整个事务会失败:
BEGIN;
<SQL>;
ROLLBACK;
2. 隔离级别⚓
针对隔离性,SQL标准定义了4种隔离级别:
Isolation Level | 脏读(Dirty Read) | 不可重复读(Non Repeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
Read Uncommitted | May | May | May |
Read Committed | - | May | May |
Repeatable Read | - | - | May |
Serializable | - | - | - |
2.1 Read Uncommitted⚓
在这种隔离级别下,一个事务会读到另一个事务更新后但未提交的数据,如果另一个事务回滚,那么当前事务读到的数据就是脏数据,这就是脏读(Dirty Read)。
2.2 Read Committed⚓
不可重复读是指,在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致。
所以正确做法就是只读一次,不要再去读了。
2.3 Repeatable Read⚓
幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。
幻读出现的原因:因为Repeatable Read下在同一个事务内的查询都是与事务开始时刻一致,所以在B事务过程中是不会读到期间A中insert的值的。
2.4 Serializable⚓
所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。但是效率会大大下降。
2.5 默认隔离级别⚓
在MySQL中,如果使用InnoDB,默认的隔离级别是Repeatable Read。