一、事务的基本要素(ACID)
- 原子性(Atomicity):事务开始后的所有操作,要么全部完成,要么全部不完成,不可能存在停留在中间环节。事务是MySQL数据库的最基本单位,就像化学中的原子一样,是物质的最基本单位。
- 一致性(Consistency):事务开始前和结束后,事务的完整性约束不会遭道破坏、
- 隔离性(Isolation):同一时间,只允许一个事务请求同一个数据,不同事务之间彼此没有干扰
- 持久性(Durability):事务完成后,事务对数据库中所有更新的数据将会永久保存,不会回滚
二、事务的并发问题
- 脏数据:脏数据是在更新数据中产生的。
假如事务A更新了一项数据X,但是还没有提交到数据库中,这个时候,事务B读取到并使用了这个数据,此时事务B读取到的数据就是一个临时的值,就是脏数据。 - 脏读:事务A更新了一个数据X,但是这个数据还没有提交到数据库中,这个时候,事务B读取到了这个数据,这个过程就叫做脏读。
- 幻读:假如事务A对一个表中的数据进行了修改,这种修改是对表中所有的数据进行了修改。与此同时,事务B也对改表进行了修改,这 种修改是对该表新增了一条数据,于是,事务A就会看到有一条数据没有修改,就好像发生了幻觉一样,这就是幻读。
- 不可重复读:事务A对某项数据读取后,事务B对该数据进行了修改,当事务A再次读取该数据时,会发现读取的数据和上次的不一样,这 就是不可重复读。
三、事务的隔离级别
- 未提交读(read-uncommitted)
- 已提交读(read-committed)
- 可重复读(repeatable-read)
- 串行化(serializable)
实例
- 未提交读:事务的最低隔离级别
A:启动事务,读取数据,此时数据为初始状态
B:启动事务,修改数据,但是不提交数据
A:再次读取数据,发现数据被修改了,读取到未提交的数据,这是脏读
B:由于某种原因,B回滚了事务
A:再次读取数据,读取到的数据为初始的数据
- 已提交读:项目中一般采用的隔离级别
A:启动事务,读取数据,此时数据为初始状态
B:启动事务,修改数据,但是不提交
A:再次读取数据,还是初始数据
B:提交事务
A:再次读取数据,数据到的是已修改的数据,这就是不可重复读
- 可重复读:MySQL默认的隔离级别
A:启动事务,读取数据,此时数据为初始状态
B:启动事务,修改数据,但是不提交
A:再次读取数据,此时数据仍是初始状态
B:提交事务
A:再次读取数据,数据仍未发生变化,说明可以重复读了
B:插入一条新的数据,并提交
A:再去读取数据,仍是初始状态,虽然可以重复读了,但是读到的数据不是最新的
A:提交本次事务,在启动一个事务,读取数据,读到的是更新的数据
由以上的实验可以得出结论,可重复读隔离级别只允许读取已提交记录,而且在一个事务两次读取一个记录期间,其他事务不得更新该记录。
- 可串行化
A:启动事务,读取数据,此时数据为初始状态
B:想启动事务B插入一条新的数据,但是发现B事务进入了等待状态,原因是因为事务A没有提交,只能等待
A:提交事务
B:事务B开始启动,发现新数据插入成功
serializable可串行化隔离级别完全锁定字段,若一个事务来查询同一份数据就必须等待,直到前一个事务完成并解除锁定为止。是完整的隔离级别,会锁定对应的数据表格,因而会有效率的问题。