首页 > 代码库 > Mysql事务隔离级别
Mysql事务隔离级别
内容一:Mysql的事务隔离级别有以下四种:
Read Uncommitted (未提交读)
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。读取未提交的数据,也被称之为脏读( Dirty Read )。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少,在实际应用中很少使用。
Read Committed (提交读)
这是大多数数据库系统的默认隔离级别(但不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读( Nonrepeatable Read ),因为同一事务的其他实例在该实例处理其间可能会有新的 commit ,所以同一 select 可能返回不同结果。
Repeatable Read (可重复读)
这是 MySQL 的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 ( Phantom Read )。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的 " 幻影 " 行。 InnoDB和 Falcon 存储引擎通过多版本并发控制( MVCC , Multiversion Concurrency Control )机制解决了该问题。
Serializable (可串行化)
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
内容二:脏读 不可重复读 幻读
脏读 (Drity Read) :某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个 RollBack 了操作,则后一个事务所读取的数据就会是不正确的。
不可重复读 (Non-repeatable read): 在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
幻读 (Phantom Read): 在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列 (Row) 数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
内容三:行级锁
Mysql的行级锁有共享锁和排它锁
SELECT ... LOCK IN SHARE MODE sets a shared mode lock on any rows that are read. Other sessions can read the rows, but cannot modify them until your transaction commits. If any of these rows were changed by another transaction that has not yet committed, your query waits until that transaction ends and then uses the latest values.
SELECT ... FOR UPDATE sets an exclusive lock on the rows read. An exclusive lock prevents other sessions from accessing the rows for reading or writing.
LOCK IN SHARE MODE 会在读取的行上加共享锁 ,其他 session 只能读不能修改或删除,如果有其他事务修改了记录,那么会等待事务提交后,再读取。
FOR UPDATE 在读取行上设置一个排他锁 。阻止其他 session 读取或者写入行数据
这样看起来似乎就能解释为什么使用 LOCK IN SHARE MODE 会产生死锁了,假如两个事务 A 、 B 都读取同一行记录,那么在这一行就加上了共享锁,但是 A 和B 事务中都需要修改这一行,那么都要等待对方释放共享锁才能进行,结果造成了死锁。
以上就是两种行级别锁的区别。
Mysql事务隔离级别