赞
踩
一提到事务大家可能优先想到的是事务的四大特性ACID(原子性、一致性、隔离性、持久性)。当提到多个事务并发操作时则必须先了解事务的隔离级别,不同的隔离级别对事务的并发操作时会有不一样的影响。本文主要介绍一下MySQL的事务隔离级别。
SQL中定义了4中隔离级别,不同的隔离级别对应着事务中做不同的修改,同时在事务内和事务间的可见性也不同。越低的隔离级别越能支持更高的并发,对系统的开销也越低。
四种隔离级别:
在read uncommitted 级别中,当在事务A中对数据的修改即使是在事务未提交的时候,其他并发操作的事务依然可以读取到事务A修改的数据,这种情况我们叫做数据“脏读”。那如果事务A在后面出现回滚的操作时,而其他事务在已经读取到的是事务A之前的修改,就会导致出现数据的修改混乱。
在read committed级别中,当一个事务A从开始直到事务提交之前,其他的并发事务对该事务的修改都是不可见的。但是在其他同一事务内执行两次一样的查询时,查询的结果也会不同,所以这个级别同时也叫做不可重复读。
其他大多数的数据库默认的隔离级别都是read committed ,但是mysql 默认隔离级别不是。
repeatable read级别是mysql 默认的事务隔离级别。该级别确保了在一个事务中多次读取结果是一致的,但同时也出现另一个“幻读”的问题。
“幻读”是指当某个事务在读取某个范围内的记录时另一个事务又在该范围内插入了新的数据,那么再次读取该范围的数据时会出现幻行。
MySQL在存储引擎(InnoDB和XtraDB)下是通过锁机制加MVCC(多版本并发控制)来解决幻读的问题。
因此也是MySQL 中默认使用的事务隔离级别,同时需要使用事务时一般使用InnoDB存储引擎。
serializable隔离级别是将各个事务强制串行执行,在每个事务执行时都会对该事务影响的数据行进行加锁,因此其他并发的事务则无法进行读写操作,需等这条事务提交后并释放锁才能进行下一个事务的执行。
由于需要对每条数据都加锁,这样就会导致大量的操作超时和锁争用的问题。
在我们的实际项目开发中很少使用这个级别。
四种隔离级别的数据一致性等级:
read uncommitted < read committed < repeatable read < serializable
四种隔离级别支持的并发等级:
read uncommitted > read committed > repeatable read > serializable
隔离级别 | 是否出现脏读 | 不可重复读 | 是否出现幻读 | 是否加锁读 |
---|---|---|---|---|
read uncommitted | 是 | 是 | 是 | 否 |
read committed | 否 | 是 | 是 | 否 |
repeatable read | 否 | 否 | 是 | 否 |
serializable | 否 | 否 | 否 | 是 |
未提交读:不存在事务之间加锁的情况,各个事务相互之间互相可见支持的并发性最高,但是由于对于数据库来说数据的准确性是我们第一考虑因素,因此这种隔离级别基本不选择。
已提交读:不同的事务之间对写的操作是互斥的,读操作不互斥。这种隔离级别和可重复读的隔离级别对比来说,它支持的并发性更高,因此很多互联网大厂(例如:阿里)会选择这种隔离级别 。对互联网大厂来讲他们往往并发量非常高,他们不希望数据库成为高并发的阻碍,可是在同一事务会出现读取数据不一致的情况,因此它们会采用其他的技术方案去追求数据的最终一致性。
可重复读:这种隔离级别对比上一个并发性则没那么高,但是数据一致性相对比较好。对于一些对数据安全性有一定要求且项目规模相对较小的团队来说选择这种隔离级别是最为合适的
可串行化:这种隔离级别对于数据一致性要求最高,并发性最低,因此对于一些涉及到资金操作,并发性和实时性不高的场景下使用。
查看数据库隔离级别
SELECT @@tx_isolation
或
show variables like 'tx_isolation'
MySQL设置隔离级别
set [global/session] transaction_isolation = "隔离级别"
global代表全局设置,使用global设置时当前会话不生效需要重开会话才有效。
session代表只在当前会话中设置。
了解了事务隔离级别也是对系统设计架构选择的必要条件,不同的隔离级别所支撑的业务类型不同,我们需要根据具体业务需要进行选择,适合的才是对好的。
在不同的数据库和不同的存储引擎中其实现的隔离级别不同,大家可以根据不同的存储引擎针对性的查阅。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。