当前位置:Gxlcms > 数据库问题 > Mysql锁机制--乐观锁 & 悲观锁

Mysql锁机制--乐观锁 & 悲观锁

时间:2021-07-01 10:21:17 帮助过:6人阅读

DROP DATABASE IF EXISTS cyhTest;
CREATE DATABASE cyhTest;

USE cyhTest;

DROP TABLE IF EXISTS employee;

CREATE TABLE IF NOT EXISTS employee (
  id      INTEGER NOT NULL,
  money   INTEGER,
  version INTEGER,
  PRIMARY KEY (id)
)
  ENGINE = INNODB;

INSERT INTO employee VALUE (1, 0, 1);

SELECT * FROM employee;
技术图片

技术图片

目前数据库中只有一条记录,且初始Money=0

2.2 测试

测试准备:

  • 还是两个会话(终端),左边会话是白色背景、右边会话是黑色背景
  • 关闭自动提交:set autocommit = 0; 

现在开始测试:

第一步:两个终端均关闭自动提交

左边:

技术图片

右边:

技术图片

第二步:左边利用 select .... for update 的悲观锁语法锁住记录

select * from employee where id = 1 for update; 

技术图片

第三步:右边也尝试利用 select .... for update 的悲观锁语法锁住记录

技术图片

可以看到,Sql语句被挂起(被阻塞)!

提示:如果被阻塞的时间太长,会提示如下:

技术图片

第四步:左边执行更新操作并提交事务

Sql语句:

update employee set money = 0 + 1 where id = 1;
commit; 

结果:

技术图片

分析:

  • Money 的旧值为0,所以更新时 Money=0+1
  • 一执行 commit 后,注意查看右边Sql语句的变化

第五步:查看右边Sql语句的变化

技术图片

分析:

  • 被左边悲观锁阻塞了 11.33 秒
  • Money=1,这是左边更新后的结果

2.3 结论

可以看到,当左边(事务A)使用了 select ... for update 的悲观锁后,右边(事务B)再想使用将被阻塞,同时,阻塞被解除后事务B能看到事务A对数据的修改,所以,这就可以很好地解决并发事务的更新丢失问题啦(诚然,这也是人家悲观锁的分内事)

第二部分 乐观锁

1 概念

1.1 理解方式一(来自网上其它小伙伴的博客)

乐观锁认为一般情况下数据不会造成冲突,所以在数据进行提交更新时才会对数据的冲突与否进行检测。如果没有冲突那就OK;如果出现冲突了,则返回错误信息并让用户决定如何去做。

1.2 理解方式二(来自网上其它小伙伴的博客)

乐观锁的特点是先进行业务操作,不到万不得已不会去拿锁。乐观地认为拿锁多半会是成功的,因此在完成业务操作需要实际更新数据的最后一步再去拿一下锁。

1.3 我的理解

理解一:就是 CAS 操作

理解二:类似于 SVN、GIt 这些版本管理系统,当修改了某个文件需要提交的时候,它会检查文件的当前版本是否与服务器上的一致,如果一致那就可以直接提交,如果不一致,那就必须先更新服务器上的最新代码然后再提交(也就是先将这个文件的版本更新成和服务器一样的版本)

乐观锁不是数据库自带的,需要我们自己去实现。

2 如何实现乐观锁呢

首先说明一点的是:乐观锁在数据库上的实现完全是逻辑的,数据库本身不提供支持,而是需要开发者自己来实现。

常见的做法有两种:版本号控制及时间戳控制。

版本号控制的原理:

  • 为表中加一个 version 字段;
  • 当读取数据时,连同这个 version 字段一起读出;
  • 数据每更新一次就将此值加一;
  • 当提交更新时,判断数据库表中对应记录的当前版本号是否与之前取出来的版本号一致,如果一致则可以直接更新,如果不一致则表示是过期数据需要重试或者做其它操作(PS:这完完全全就是 CAS 的实现逻辑呀~)

至于时间戳控制,其原理和版本号控制差不多,也是在表中添加一个 timestamp 的时间戳字段,然后提交更新时判断数据库中对应记录的当前时间戳是否与之前取出来的时间戳一致,一致就更新,不一致就重试。

特点

乐观并发控制相信事务之间的数据竞争概率是较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁

Mysql锁机制--乐观锁 & 悲观锁

标签:需要   class   分析   database   ble   业务   个数   方式   timestamp   

人气教程排行