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


进一步的问题是:有没有可能使用乐观锁来实现RDBMS中的写一致性?有没有可能使用乐观锁实现完整的ACID特性?
回答是可以 。例如,MS SQL SERVER的Hekaton引擎通过一套基于时间戳的多版本管理系统,实现了不使用了悲观锁的ACID 。
但是,这并不意味着乐观锁必然优于悲观锁 。除了维护多版本的开销以外,乐观锁无法避免的一个问题是 , 当多个写操作试图更新同一个对象时,只有第一个操作可以成功,其它的操作都会在Compare时失败然后回滚,从而造成极大的性能问题 。在这种情况下,乐观锁的性能会低于悲观锁 。
目前的趋势似乎是,大规模的分布式数据库更倾向于使用乐观锁来达到所谓的external consistency,因为基于传统悲观锁的分布式锁在集群大到一定程度以后(从几百台扩展到成千上万台时),性能开销就大得无法接受了 。Google的Spanner就是基于乐观锁 。当然这完全是另外一个问题了 。
mysql 解决可提交读、可重复读、幻读这张图本人觉得总结得挺好的,在一般的互联网项目中,基本上用的都是Innodb引擎,一般只涉及到的都是行级锁,但是如果sql语句中不带索引进行操作,可能会导致锁表,这是不推荐的,性能非常低 , 可能会导致全表扫描等 , 行锁的具体实现算法有以下几种mysql特有的锁:
【mysql乐观锁怎么写 炒股软件文字出现乱码怎么办?】Record Lock(记录锁):单个行记录的锁,一般是唯一索引或者主键上的加锁
Gap Lock(间隙锁):锁定一个区间,但是不包括自身,开区间的锁,RR级别才会有间隙锁 , 间隙锁的唯一目的是防止区间数据的插入,所以间隙锁与间隙锁之间是不会相互阻塞的
Next-key Lock(临键锁):与间隙锁的区别是包括自身,是左开右闭区间 , RR级别才会有
加锁规则里面,包含了两个“原则”、两个“优化”和一个“bug” 。
原则 1:加锁的基本单位是 next-key lock,希望你还记得 , next-key lock 是前开后闭区间 。
原则 2:查找过程中访问到的对象才会加锁 。
优化 1:索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁 。
优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候 , next-key lock 退化为间隙锁 。
一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止 。
举例来说明上述的原则:
建表
插入数据:
INSERT INTOt ( id ,c ,d ) VALUES (0, 0, 0);
INSERT INTOt ( id ,c ,d ) VALUES (5, 5, 10);
INSERT INTOt ( id ,c ,d ) VALUES (10, 10, 10);
INSERT INTOt ( id ,c ,d ) VALUES (15, 15, 15);
INSERT INTOt ( id ,c ,d ) VALUES (20, 20, 20);
INSERT INTOt ( id ,c ,d ) VALUES (25, 25, 25);
例子1:锁表
因为d字段上没有建索引,所以涉及该字段的查询加锁会锁住整个表
因为d字段上面没有建立索引,所以事务1执行后会导致整个表被锁 , 后面所有的操作都会在等待整个表锁被释放
例子2:主键/唯一索引 记录锁
id字段为主键,而且事务1查询命中了唯一的记录,默认是加Next-key Lock,区间是(0,5],但是根据优化1,唯一索引/主键上的等值查询,会退化为行锁,所以只会锁5这个记录 。
例子3:主键/唯一索引上的间隙锁
由于表 t 中没有 id=7 的记录,所以用我们上面提到的加锁规则判断一下的话:根据原则 1 , 加锁单位是 next-key lock,事务1加锁范围就是 (5,10];同时根据优化 2,这是一个等值查询 (id=7) , 而 id=10 不满足查询条件,next-key lock 退化成间隙锁,因此最终加锁的范围是 (5,10),所以事务2会阻塞,事务3执行成功 。

推荐阅读