范文无忧网公文文书公文写作

生产环境上mysql事务隔离级别设置成哪个级别

02月10日 编辑 fanwen51.com

术式之后皆为逻辑,一切皆为需求和实现。希望此文能从需求、现状和解决方式的角度帮大家理解隔离级别。 隔离级别的产生 在串型执行的条件下,数据修改的顺序是固定的、可预期的结果,但是并发执行的情况下,数据的修改是不可预期的,也不固定,为了实现数据修改在并发执行的情况下得到一个固定、可预期的结果,由此产生了隔离级别。 所以隔离级别的作用是用来平衡数据库并发访问与数据一致性的方法。 事务的4种隔离级别 READ UNCOMMITTED 未提交读,可以读取未提交的数据。READ COMMITTED 已提交读,对于锁定读(select with for update 或者 for share)、update 和 delete 语句, InnoDB 仅锁定索引记录,而不锁定它们之间的间隙,因此允许在锁定的记录旁边自由插入新记录。 Gap locking 仅用于外键约束检查和重复键检查。REPEATABLE READ 可重复读,事务中的一致性读取读取的是事务第一次读取所建立的快照。SERIALIZABLE 序列化 在了解了 4 种隔离级别的需求后,在采用锁控制隔离级别的基础上,我们需要了解加锁的对象(数据本身&间隙),以及了解整个数据范围的全集组成。 数据范围全集组成 SQL 语句根据条件判断不需要扫描的数据范围(不加锁); SQL 语句根据条件扫描到的可能需要加锁的数据范围; 以单个数据范围为例,数据范围全集包含:(数据范围不一定是连续的值,也可能是间隔的值组成) 1. 数据已经填充了整个数据范围:(被完全填充的数据范围,不存在数据间隙) 整形,对值具有唯一约束条件的数据范围 1~5 ,已有数据

1、

2、

3、

4、5,此时数据范围已被完全填充; 整形,对值具有唯一约束条件的数据范围 1 和 5 ,已有数据

1、5,此时数据范围已被完全填充; 2. 数据填充了部分数据范围:(未被完全填充的数据范围,是存在数据间隙) 整形的数据范围 1~5 ,已有数据

1、

2、

3、

4、5,但是因为没有唯一约束,所以数据范围可以继续被 1~5 的数据重复填充; 整形,具有唯一约束条件的数据范围 1~5 ,已有数据 2,5,此时数据范围未被完全填充,还可以填充

1、

3、4 ;3. 数据范围内没有任何数据(存在间隙) 如下: 整形的数据范围 1~5 ,数据范围内当前没有任何数据。在了解了数据全集的组成后,我们再来看看事务并发时,会带来的问题。无控制的并发所带来的问题 并发事务如果不加以控制的话会带来一些问题,主要包括以下几种情况。1. 范围内已有数据更改导致的: 更新丢失:当多个事务选择了同一行,然后基于最初选定的值更新该行时,由于每个事物不知道其他事务的存在,最后的更新就会覆盖其他事务所做的更新; 脏读: 一个事务正在对一条记录做修改,这个事务完成并提交前,这条记录就处于不一致状态。这时,另外一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做了进一步的处理,就会产生提交的数据依赖关系。这种现象就叫“脏读”。2. 范围内数据量发生了变化导致: 不可重复读:一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变,或者某些记录已经被删除了。这种现象就叫“不可重复读”。 幻读:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象称为“幻读”。可以简单的认为满足条件的数据量变化了。因为无控制的并发会带来一系列的问题,这些问题会导致无法满足我们所需要的结果。因此我们需要控制并发,以实现我们所期望的结果(隔离级别)。MySQL 隔离级别的实现 InnoDB 通过加锁的策略来支持这些隔离级别。行锁包含: Record Locks 索引记录锁,索引记录锁始终锁定索引记录,即使表中未定义索引,这种情况下,InnoDB 创建一个隐藏的聚簇索引,并使用该索引进行记录锁定。 Gap Locks 间隙锁是索引记录之间的间隙上的锁,或者对第一条记录之前或者最后一条记录之后的锁。间隙锁是性能和并发之间权衡的一部分。对于无间隙的数据范围不需要间隙锁,因为没有间隙。 Next-Key Locks 索引记录上的记录锁和索引记录之前的 gap lock 的组合。假设索引包含

10、

11、13 和 20。可能的next-key locks包括以下间隔,其中圆括号表示不包含间隔端点,方括号表示包含端点: (负无穷大, 10] (10, 11] (11, 13] (13, 20] (20, 正无穷大) 对于最后一个间隔,next-key将会锁定索引中最大值的上方,左右滑动进行查看"上确界"伪记录的值高于索引中任何实际值。上确界不是一个真正的索引记录,因此,实际上,这个 next-key 只锁定最大索引值之后的间隙。基于此,当获取的数据范围中,数据已填充了所有的数据范围,那么此时是不存在间隙的,也就不需要 gap lock。对于数据范围内存在间隙的,需要根据隔离级别确认是否对间隙加锁。默认的 REPEATABLE READ 隔离级别,为了保证可重复读,除了对数据本身加锁以外,还需要对数据间隙加锁。READ COMMITTED 已提交读,不匹配行的记录锁在 MySQL 评估了 where 条件后释放。对于 update 语句,InnoDB 执行 "semi-consistent" 读取,这样它会...

推荐阅读
图文推荐
栏目列表