3.1 事务隔离级别
什么是事务?
事务是并发控制的基本单位,是一个操作序列,这些操作要么全都执行,要么全都不执行,比如,小明给小红转账100元,小明账户扣除100元,小红账户增加100元,这两个操作要么不执行,要么一起执行,所以,应该把这当做同一个事务。
事务的特性(ACID)
原子性(Atomicity):事务是最小的执行单位,不允许分割,事务的原子性确保动作要么全部完成,要么完全不起作用;
一致性(Consistency):执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
持久性(Durability):一个事务被提交之后,它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
并发事务带来的问题
多个事务并发运行,比如多个用户同时对同一个数据库操作,可能会导致下面的问题: (1)脏读(Dirty read) 当一个事务正在访问数据并对数据进行了修改,而这种修改还没有提交到数据库中,另外一个事务也访问了这个数据,然后使用了这个数据,因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据就是“脏数据”。 比如,数据表中A=1,事务1(Task1,T1):读取A=1,并修改A=2,但还没有提交到数据库;事务2:读取A=1。此时就是脏读。 (2)丢失修改(Lost to modify) 一个事务读取一个数据并修改,另一个事务也读取并修改,第一个事务读取并修改的结果就会丢失。 比如,数据表中A=1,事务1:读取A=1,并修改A=2,但还没有提交到数据库;事务2:读取A=1,并修改A=3,提交到数据库。此时A=3,事务1的修改的数据丢失。 (3)不可重复读(Unrepeatable read) 一个事务多次重复读取同一个数据,在读取之间,另一个事务读取并修改数据,造成第一个事务两次读取的数据结果不一致。 比如,数据表中A=1,事务1:读取A=1;事务2:读取A=1,并修改A=2,提交到数据库;数据1:读取A=2。此时事务A两次读取的同一数据A的值并不一致。 (4)幻读(Phantom read) 一个事务读取了几行数据之后,另一个数据读取并增加或者删除了几行数据,造成第一个事务多读了不存在的数据或者数据消失了。
事务隔离级别
为了应对并发事务带来的问题,SQL定义了四个隔离级别:
READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许读取尚未提交的数据变更,可能会造成脏读、不可重复读或幻读;
READ-COMMITTED(读取已提交):允许读取并发事务已经提交的数据,可以阻止脏读,但不能阻止不可重复读或幻读;
REPEATABLE-READ(可重复读):对同一字段多次读取结果都是一致的,除非数据是事务本身修改,可以阻止脏读和不可重复读,但不能阻止幻读;
SERIALIZABLE(串行化):最高的隔离级别,完全服从ACID隔离级别,所有事务依次逐个执行,这样事务之间就完全不可能产生干扰,可以阻止脏读、不可重复读、幻读。
隔离级别
脏读
不可重复读
幻读
Read uncommitted
√
√
√
Read committed
x
√
√
Repeatable read
x
x
√
Serializable
x
x
x
MySQLInnoDB存储引擎默认支持的隔离级别是Repeatable-read,MySQL8+可以使用 SELECT @@transaction_isolation;
来查询数据库隔离级别。
TODO:MySQL实操
Last updated
Was this helpful?