美文网首页程序员
初识“乐观锁”和“悲观锁”

初识“乐观锁”和“悲观锁”

作者: 叫我宫城大人 | 来源:发表于2017-11-20 21:10 被阅读44次

一、前言

还记得前段时间手头项目初识阶段,团队一大神code review时提及“乐观锁”,我心里一懵,哇,这是什么东西,感觉好叼的样子!是的,我根本就母鸡这是什么意思,有何用途,如何正确使用。

最近浏览别人的面经时看到这个话题,在此做个简单的入门,也好在以后的面试中不是一再重复面试官的问题。(〃'▽'〃)

二、概念

个人理解,这里的锁是针对数据库而言的。像synchronized关键字是对于Java程序而言的。就“乐观锁”和“悲观锁”字面上讲,可以简单作出如下解释:

乐观锁:及其乐观,认为我从数据库取数据时没有其他操作修改该数据,在更新时会把将要更新的数据与之前取出的数据作出对比,如果有过修改,则更新不成功。比对的方法通常采用字段添加一个版本号,更新数据行时顺带更新这个版本号;

悲观锁:非常悲观,获取数据时害怕其他人修改本条数据,将其锁住(这里分为“row lock”和“table lock”,后续会简单提及),然后在自己操作完成后将其锁释放。在此期间,对本记录的操作都将阻塞;

三、简单实现

假如我们有张数据表student作为基础数据:

id name version
1 张三 0
2 李四 0
3 王五 0

1、乐观锁

查询sql语句为:

select id, name, version from student;

更新语句为:

update  
  name = #{name}, 
  version = version + 1
from student 
where id = #{id} and version = #{version};

很清楚查询就是普通的sql,但是更新时会检查在拿到查询结果到执行更新操作期间内version是否有过变动;如果是有过变动where条件不满足那么执行完sql后受影响行数为0,则达到了乐观锁的效果。

2、悲观锁

真正的给数据表加锁,需要手动控制事务的提交。MySQL的事务默认是自动提交,我们需要设置为手动提交:

set autocommit = 0;

查询时需要运用到数据库sql的特性for update

select * from student where id = 1 for update;

注意:这里查询条件若是主键的话,则是row lock(行锁),不影响其他数据的操作,若是其他条件或是没有条件的话,则是table(表锁),整个表都会被锁住,知道该事务提交。而且这里的操作sql都是针对for update而言的,普通sql不会造成影响。

为了验证悲观锁的特性,我们开启两个mysql的console,方便区分,取名为left,right;

left:

set autocommit = 0;
begin;
select * from student where id = 1 for update;

输出:

id name version
1 张三 0

但是注意我们的事务还没有提交,切换到right控制台:

select * from student where id = 1 for update;

发现控制台一直等待,一段时间后就会抛出错误信息:

1205 - Lock wait timeout exceeded; try restarting transaction

提示很清楚,锁超时了。然后我们再次执行right控制台同样的语句,同样阻塞在等待获取锁,切换到left的控制台,执行commit;命令提交事务,再次切换到right控制台,发现已经输出:

id name version
1 张三 0

如果去掉where的查询条件会发生表锁,其他数据也不能获取到,有兴趣可自行实践。

四、后话

只是一个简单的入门,目前工作很少应用,先尝尝鲜。并不是所有你不知道的,都是那些高大上,及其难的知识点,在亲自实践过后再怀疑人生吧。
( ̄▽ ̄)/

相关文章

  • 看完你就知道的乐观锁和悲观锁

    看完你就知道的乐观锁和悲观锁 Java 锁之乐观锁和悲观锁 [TOC] Java 按照锁的实现分为乐观锁和悲观锁,...

  • 初识“乐观锁”和“悲观锁”

    一、前言 还记得前段时间手头项目初识阶段,团队一大神code review时提及“乐观锁”,我心里一懵,哇,这是什...

  • 乐观锁和悲观锁

    参考来源 深入理解乐观锁与悲观锁 乐观锁的一种实现方式——CAS mysql乐观锁总结和实践 乐观锁和悲观锁 悲观...

  • 锁的概述

    乐观锁与悲观锁 悲观锁 乐观锁和悲观锁的概念出自数据库,但在java并发包中也引入和类似的概念(乐观锁/悲观锁是一...

  • 并发参数

    悲观锁与乐观锁 悲观锁 synchronized和ReentrantLock等独占锁就是悲观锁思想的实现乐观锁一般...

  • CAS 与原子操作

    乐观锁与悲观锁 锁可以从不同的角度分类。其中,乐观锁和悲观锁是一种分类方式。 乐观锁:乐观锁又称为“无锁”。乐观锁...

  • 04 番外(待补充AQS相关原理) Java多线程中的各种锁

    1 乐观锁 悲观锁 1.1 乐观锁 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设...

  • Mysql锁

    按照使用方式,锁分为: 悲观锁 乐观锁 乐观锁 概念就不细讲了,乐观锁和悲观锁的区别是乐观锁是假设在修改数据之前,...

  • MySQL之乐观锁·MVCC

    一、 乐观锁 和 悲观锁 乐观锁 和 悲观锁 是实现并发操作的两种不同的 加锁思想,其中: 乐观锁 假设:操作能成...

  • 蚂蚁面试

    1、mysql乐观锁和悲观锁的区别? 乐观锁通过MVCC,版本实现,悲观锁select... for update...

网友评论

    本文标题:初识“乐观锁”和“悲观锁”

    本文链接:https://www.haomeiwen.com/subject/bkdbvxtx.html