mysql乐观锁怎么写 炒股软件文字出现乱码怎么办?( 四 )


例子4:普通索引上的间隙锁
c字段是普通索引 , 事务1执行时默认是对区间(0,5]加间隙锁,根据优化2,非唯一索引/主键会继续向右遍历,找到10,所以最终的加锁为(0,5]的Next-Key锁+(5 , 10)的间隙锁,所以事务2阻塞,事务3成功 。
例子5:间隙锁与行锁
事务1默认的Next-Key锁区间是(0 , 5],根据优化2会向右遍历,找到不满足查询条件的10,退化成间隙锁,所以事务1的锁是(0,5]的Next-Key锁+(5,10)的间隙锁,这两个锁与行锁是冲突的,而事务2申请的Next-Key锁是和事务1一样,但是c=5的行锁与事务1冲突,所以产生了阻塞,如果改为update t set d=1000 where c=6;因为此时产生的间隙锁为(5,10),而间隙锁与间隙锁是不冲突的,不会产生阻塞
例子6:lock in share mode锁覆盖索引
事务1存在覆盖索引的情况,不会去回表,lock in share mode这种情况下只会锁c字段索引,而事务2是对主键加行锁,所以两者不存在冲突 。
例子7:主键/唯一索引上的范围查询
开始执行的时候,要找到第一个 id=10 的行,因此本该是 Next-Key Lock(5,10],根据优化 1 ,  主键 id 上的等值条件,退化成行锁,只加了 id=10 这一行的行锁 。范围查找就往后继续找,找到 id=15 这一行停下来,因此需要加 Next-Key Lock(10,15],所以事务3是冲突的 。
例子8:普通索引上的范围查询
开始执行时,找到第一个满足条件的行10,加锁Next-Key Lock(5,10],因为不是唯一索引,所以不会退化,继续向后面找,找到15这一行停下来,因此需要加 Next-Key Lock(10,15] , 因为是范围查询,所以锁不会退化 。
快照读: 通过MVCC实现,该技术不仅可以保证innodb的可重复读,而且可以防止幻读,但是他读取的数据虽然是一致的 , 但是数据是历史数据 。
简单的select操作(不包括 select … lock in share mode, select … for update)
当前读: 要做到保证数据是一致的,同时读取的数据是最新的数据,innodb提供了next-key lock,即gap锁与行锁结合来实现 。
select … lock in share mode
select … for update
insert
update
delete
自己理解:
简单的select是快照读,快照读实现可提交读,可重复读和幻读是通过MVCC+ReadView实现的,而当前读实现这几种是通过锁来实现的,为了说明具体原理,下面介绍下MVCC和ReadView概念,所以简单的select是通过乐观锁实现的,当前读是通过悲观锁实现的 。
参考文章:
mysql 使用乐观锁时,自带的悲观锁会失效么这是两个不同的概念 。
1.在表中增加version,是由你自己写的程序或者sql的where条件控制的,并没有真正的到达mysql的事务层 。
2.悲观锁是mysql自己维护的锁机制,你加不加version跟悲观锁没关系 , 而只跟你设置的事务级别有关系
MySql-硬核知识多版本并发控制(Multi-Version Concurrency Control,MVCC)是MySQL中基于乐观锁理论实现隔离级别mysql乐观锁怎么写的方式mysql乐观锁怎么写,用于实现读已提交和可重复读 。
具体实现
在MySQL中,会在表中每一条数据后面添加两个字段:
有序数组:范围查询和等值查询性能好,使用二分法查找,更新麻烦 。
普通索引和唯一索引在查询性能上相差不大,性能差异主要体现在更新时 。
更新一条数据时, 如果内存中有就直接更新,如果没有innoDb会将这些操作缓存到changeBuff中,
()changeBuff是poolBuffmysql乐观锁怎么写的一部分),这样就不用加载数据页了 , mysql后台线程定期将changeBuff merge入磁盘 。
唯一索引因为要判断数据是否重复,必须将数据页全部读入内存,再更新内存,而普通索引只需将操作缓存在changeBUff中即可 , 

推荐阅读