MySQL事务基本原理及隔离级别

1、什么是事务:

事务是应用程序中一组严密的操作,所有的操作必须成功,否则每个操作中所做的更改将全部撤销。mysql事务可以看作是一组SQL语句的集合。事务具有4个性质,即ACID性。

A:Atomicity,原子性。事务是不可分割的,事务中的操作要么全做,要么都不做。

C:Consistency,一致性。事务执行的结果就是将数据库从一个一致性转换到另一个一致性。因此当事务成功执行时,就说数据库处于一致性状态。如果数据库运行中发生故障,有些事务尚未完成就中断,这些中断的事务有有一部分已经写入数据库,这时数据库就处于不一致的状态。

I:Isolation,隔离性。一个事务的执行不能有其他事务的干扰,并发执行的各个事务之间相互隔离。

D:Durability,持续性,也称为永久性。指一个事务一旦提交,他对数据库的影响应该是永久的。

2、事务的基本原理:事务提交就会将结果永久化,不提交就不会。我们不开启事务,执行一条普通的SQL语句,马上就会持久化数据,这是因为mysql默认对SQL语句的执行是自动提交的。也就是说开启了事务就相当于关闭了mysql的自动提交功能,而需要自己手动进行commit。

3、事务的4种隔离级别:--低隔离级别一般支持更高的并发处理,并拥有更低的系统开销。

第一级别:读取未提交内容(Read Uncommit):

(1)本级别所有事务都可以看到其他未提交事务的执行结果

(2)本隔离级别很少进行实际应用,因为他的性能并不比其余的级别高

(3)本级别会产生的问题--脏读(Dirty Read):读取到其他事务未提交的数据

时间转账事务A取款事务B
T1
开始事务
T2开始事务
T3
查询账户余额为1000元
T4
取出500元把余额改为500元
T5查询账户余额为500元(脏读)
T6
撤销事务余额恢复为1000元
T7汇入100元把余额改为600元
T8提交事务

A读取了B尚未提交的脏数,导致最后余额为600元。

第二级别:读取到提交内容(Read Commit):

(1)这是大多数数据库的默认级别

(2)一个事务只能看见已经提交事务的执行结果

(3)本级别会出现的问题--不可重复读(Nonrepeatable Read):同一个事务在不同时间执行完全相同的SQL语句会出现不一样的结果。

时间取款事务A转账事务B
T1
开始事务
T2开始事务
T3
查询账户余额为1000元
T4查询账户余额为1000元
T5
取出100元把余额改为900元
T6
提交事务
T7查询账户余额为900元(和T4读取的不一致)

可以看到最后读取的数据不一致。

第三级别:可重复读(Repeatable Read)

(1)这是mysql默认的隔离级别

(2)这确保同一事务的多个实例在并发读取数据时会看到相同的数据

(3)本级别可能会出现的问题--幻读(Phanton Read):幻读与不可重复读类似,都是不同时间查询出的数据不一致,不过幻读针对的是新增数据,而不可重复读针对的是修改数据

(4)InnoDB和Falcon存储引擎通过多版本并发控制(MVCC)机制解决了该问题

时间统计金额事务A转账事务B
T1
开始事务
T2开始事务
T3统计总存款数为10000元
T4
新增一个存款账户,存款为100元
T5
提交事务
T6再次统计总存款数为10100元(幻象读)

更新丢失

两个事务对同一数据进行更新,后者会覆盖先者的更新。

时间取款事务A转账事务B
T1开始事务
T2
开始事务
T3查询账户余额为1000元
T4
查询账户余额为1000元
T5
汇入100元把余额改为1100元
T6
提交事务
T7取出100元将余额改为900元
T8撤销事务
T9余额恢复为1000元(丢失更新)

第四级别:Serilizable(可串行化)

(1)这是最高的隔离级别

(2)他通过强制事务排序,使之不可能发生冲突,从而解决幻读问题。简而言之,他在每个读的数据行上加上了共享锁(即该行只能被读取而不能被更改)

(3)这个级别可能导致大量的超时现象和锁竞争

隔离级别读数据一致性脏读不可重复读幻读
未提交读(Read uncommitted)最低级别,只能保证不读取物理上损坏的数据
已提交读(Read committed)语句级
可重复读(Repeatable read)事务级
可序列化(Serializable)最高级别,事务级


书山有路勤为径 学海无涯苦作舟