详细见:
- 三分钟图解事务隔离级别,看一遍就懂
- 数据库中事务指的是什么
“锁" 是数据库系统区别于文件系统的一个关键特性,其对象是事务,用来锁定的是数据库中的对象,如表、页、行等。锁确实提高了并发性,但是却不可避免地存在一些潜在的并发一致性问题。
不过好在锁只会带来四种问题(丢失更新、脏读、不可重复读、幻读),如果可以防止这四种情况的发生,那将不会产生并发异常。为此,ISO 和 ANIS SQL 标准制定了四种事务隔离级别标准,用来对应地解决锁带来的几种问题。
1.事务概念
事务是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元);
事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为原子性、一致性、隔离性和持久性 (ACID) 属性,只有这样才能成为一个事务。事务一般都是与数据库打交道的操作.
事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。
2.事务的四大特性
1 )原子性
事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
2 )一致性
事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。
3 )隔离性
一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
4 )持续性
也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
3.事务的隔离级别
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。
-
读未提交(Read Uncommitted)
引发脏读(读取了未提交的数据) -
读已提交(Read Committed)
这是大多数数据库系统默认的隔离级别,但不是MySQL默认的
只能看见已经提交事务所做的改变
引发不可重复读,不可重读读意味着我们同一事务执行完全相同的select语句时可能看到不一样的结果。
导致这种情况的原因可能有:(1)有一个交叉的事务有新的commit,导致了数据的改变;(2)一个数据库被多个实例操作时,同一事务的其他实例在该实例处理其间可能会有新的commit
多个commit提交时,只读一次出现结果不一致 -
可重复读(Repeatable Read)
这是MySQL的默认事务隔离级别
它确保同一事务的多个实例在并发读取数据时,看到同样的数据行
此级别可能出现的问题–幻读(Phantom Read),当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行
InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题 -
可串行化(Serializable)
这是最高的隔离级别
它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它在每个读的数据行上加上共享锁。
可能导致大量的超时现象和锁竞争
3.事务隔离级别
SQL 标准定义了四种越来越严格的事务隔离级别,用来解决我们上述所说的四种事务的并发一致性问题。
-
READ UNCOMMITTED 读取未提交:事务中的修改,即使没有提交,对其它事务也是可见的。
上面提到过,数据库本身其实已经具备阻止丢失更新的能力,也就是说,即使是最低的隔离级别也可以阻止丢失更新问题。所以:
这个隔离级别可以阻止 丢失更新 -
READ COMMITTED 读取已提交:一个事务只能读取已经提交的事务所做的修改。换句话说,一个事务所做的修改在提交之前对其它事务是不可见的。
这个隔离级别可以阻止 丢失更新 + 脏读 -
REPEATABLE READ 可重复读(InnoDB 存储引擎默认的隔离级别):保证在同一个事务中多次读取同一数据的结果是一样的
这个隔离级别可以阻止 丢失更新 + 脏读 + 不可重复读 -
SERIALIZABL 可串行化:强制事务串行执行(需要使用锁机制来实现),这样多个事务互不干扰,不会出现并发一致性问题。
这个隔离级别可以阻止 丢失更新 + 脏读 + 不可重复读 + 幻读
可以看到四种隔离级别能阻止的并发一致性问题越来越多,但并不代表越高的隔离级别就越好,因为事务隔离级别越高,数据库付出的性能代价也就相应地越大。