MySQL行锁怎么开启 mysql 行锁锁住的是什么( 二 )


事务A读到了事务B未提交的数据 。(read uncommitted)
事务A第一次读取行num,此时事务B修改行num并提交,事务A再读行num,数据会发生变化 。(read uncommitted, read committed)
事务A第一次查询范围query_range,返回n行,此时事务B在该查询范围内插入了一行数据并提交,事务A再次查询范围query_range会看到B插入的数据 。(read uncommitted, read committed, repeatable read)
在同一个事务执行过程中,两次相同的查询,但是查询的返回数据行数不同 。
开启sessionA, sessionB
此时锁(行锁、gap锁)的情况如下图,标红为加锁 , 采用next key lock 。(不光在索引a上加锁 , 索引a中3所对应的主键索引也会加锁 , 只画了索引a)
注意:这里是主键索引的顺序与a索引的顺序一致的情况 。一致的情况下,新插入的4会插入在原来的4之后 。MySQL行锁怎么开启我们定义函数index_key(x), 表示获取x所对应的主键索引,new(x)表示新插入的x,old(x)表示已经存在的x 。如果index_key(old(4))index_key(new(4)) , 那新的4是插不进去的,因为新的4会被放在老的4的前面 。同理,新插入的2也有可能插入进去(只要index_key(new(2))index_key(old(2))) 。具体的例子整理后发出
对于sessionB,插入2,3失败,插入4成功 。(如图lock.png,新插入的2会被2与3之间gap锁阻止,新插入的3肯定失败,但是新插入的4就没问题)
开启sessionA:
这个时候情况如下图所示:
如果按照实例1的分析,不看主键索引id,应该插入(id=4,a=3)应该会被gap锁锁定,但是事实是可以插入成功 。因为插入的(i4=d,a=3)放在了(id=5,a=3)的上面 。
同样的道理,不看主键索引id,通过实例1的分析,插入(id=6,a=7)应该可以插入,但是事实不行 , 因为(id=6,a=7)被a=5与a=7之间的gap锁阻止了 。
新插入的(id=4, a=3),需要判断会插入在(id=5, a=3)之前还是之后,很明显之前(45),那么(id=3, a=5)与(id=5, a=3)之间的gap锁不会阻止 。
新插入的(id=6, a=7),需要判断会插入在(id=7, a=7)之前还是之后 , 很明显之前(67),那么(id=6, a=7)会被(id=3, a=5)与(id=5, a=3)与(id=7, a=7)之间的gap锁阻止 。
MySQL从入门到精通(九) MySQL锁,各种锁 锁是计算机协调多个进程或线程并发访问某一资源的机制MySQL行锁怎么开启,在数据库中,除传统的计算资源(CPU、RAM、I/O)争用外 , 数据也是一种供许多用户共享的资源 , 如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说,锁对数据库而言是尤其重要,也更加复杂 。MySQL中的锁,按照锁的粒度分为:1、全局锁,就锁定数据库中的所有表 。2、表级锁,每次操作锁住整张表 。3、行级锁,每次操作锁住对应的行数据 。
全局锁就是对整个数据库实例加锁 , 加锁后整个实例就处于只读状态 , 后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将阻塞 。其典型的使用场景就是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性 。但是对数据库加全局锁是有弊端的 , 如在主库上备份,那么在备份期间都不能执行更新,业务会受影响,第二如果是在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志,会导致主从延迟 。
解决办法是在innodb引擎中 , 备份时加上--single-transaction参数来完成不加锁的一致性数据备份 。
添加全局锁: flush tables with read lock; 解锁 unlock tables 。

推荐阅读