mysql乐观锁实现

mysql乐观锁实现各锁的概念 悲观锁 假定会发生并发冲突 屏蔽一切可能违反数据完整性的操作悲观锁 从字面理解就是很悲观 每次去拿数据的时候都认为别人会修改 所以在每次拿的时候对数据上锁 这样就保证了数据的准确性 比如 mysql 中的表锁 行锁 表锁 当你对一张表进行修改时 会锁死整张表 其他的请求需要在修改完成释放锁才能继续 在高并发的情景下不适用 行锁 当你对一张表的某一行数据修改时 会锁死这一行数

各锁的概念:

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作

悲观锁,从字面理解就是很悲观,每次去拿数据的时候都认为别人会修改,所以在每次拿的时候对数据上锁,这样就保证了数据的准确性。比如mysql中的表锁,行锁。

表锁:当你对一张表进行修改时,会锁死整张表,其他的请求需要在修改完成释放锁才能继续。在高并发的情景下不适用。

行锁:当你对一张表的某一行数据修改时,会锁死这一行数据,对表中其他的数据没影响。行锁在保证数据准确性的同时也保证了效率,但一定程度上增加了系统的开销

乐观锁: 假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。

乐观锁,在每次去拿数据的时候认为别人不会修改,不对数据上锁,但是在提交更新的时候会判断在此期间数据是否被更改,如果被更改则提交失败。

 

乐观锁的实现:

使用版本控制字段,再利用行锁的特性实现乐观锁,如下

有一张订单表order,有字段id、order_no、 price,  为实现乐观锁控制,添加version字段,默认值为0

order
id 1
order_no
price 5
version 0

假设两个人同时进来修改该条数据,操作为:

1. 先查询该数据   select * from order where id = 1

2. 修改该条数据  update order set price = 1 where id = 1

如果两个人同时查询到该条数据price = 5, 可以执行update操作, 但任意一方还没执行update操作,那么最后双方都执行update,导致数据被修改两次,产生脏数据 !

使用version字段控制版本后:

1. 两人先查询该数据 select * from order where id = 1

此时两人查询到的数据一样,id = 1, price = 5, order_no = , version = 0

2. 两人都发现该条数据price = 5, 符合update条件,第一人执行update(因为mysql行锁的特性,两人不可能同时修改一条数据,所以update同一条数据的时候,是有先后顺序的,只有在第一个执行完update,才能释放行锁,第二个继续进行update): 

update order set price = 1, version = version + 1 where id = 1 and version = 0

执行完成后,version字段值将变成1, 第二人执行update:

update order set price = 1, version = version + 1 where id = 1 and version = 0

此时的version的值已经被修改为1,所以第二人修改失败,实现乐观锁控制。

 

死锁的处理:

数据库使用乐观锁导致产生死锁:

事务A

update order set price = 1 where id = 1

update order set price = 2 where id = 2

事务B

update order set price = 1 where id = 2

update order set price = 2 where id = 1

假设在两个事务中有以上两个操作,同时修改order表中两条数据

事务A在执行完第一条update的时候,刚好事务B也执行完第一条update

此时, 事务A中order表中的id = 1的行被锁住, 事务B中order表中id = 2的行被锁住,两个事务继续往下执行

事务A中第二条update执行需要order表中id = 2的行数据,而事务B中第二条update执行需要id = 1的行数据, 两条update往下执行的条件都需要对方事务中已经被锁住的行,于是陷入无限等待,形成死锁。

解决死锁的产生:

指定锁的执行顺序,比如把以上两事务稍作修改

事务A

update order set price = 2 where id = 2

update order set price = 1 where id = 1

事务B

update order set price = 1 where id = 2

update order set price = 2 where id = 1

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/176925.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午8:42
下一篇 2026年3月26日 下午8:43


相关推荐

  • linux 搭建webserver-BOA

    linux 搭建webserver-BOA嵌入式 linux 搭建 webserver BOA

    2026年3月16日
    1
  • SQLyog 报错2058 :连接 mysql 8.0.11 解决方法

    SQLyog 报错2058 :连接 mysql 8.0.11 解决方法今天闲来无事,下载新版的 mysql8.0.11安装。为了方便安装查看,我下载了sqlyog工具连接mysql配置新连接报错:错误号码2058,分析是mysql密码加密方法变了。解决方法:windows下cmd登录mysql-uroot-p登录你的mysql数据库,然后执行这条SQL: ALTERUSER’root’@’localhost’IDENTIFI…

    2022年10月3日
    3
  • C语言:质数和合数的判断

    C语言:质数和合数的判断给定一个正整数 n 2 lt n lt 10000 判断是否为质数 多组输入 每行一个 n 2 lt n lt 10000 对于每一组数 如果是质数则输出 Yes 否则输出 No 循环的运用 while scanf nbsp amp nbsp EOF nbsp 多组输入循环 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp for 循环 include

    2026年3月17日
    2
  • QQ支持接入「小龙虾」

    QQ支持接入「小龙虾」

    2026年3月13日
    2
  • 什么是lamp架构_什么是LAMP

    什么是lamp架构_什么是LAMPLAMP架构介绍LAMP动态网站架构LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写。1、LAMP分别代表什么?L代表服务器操作系统使用LinuxA代表网站服务使用的是Apache软件基金会中的httpd软件M代表网站后台使用的数据库是MySQL数据库P代表网站是使用PHP/Perl/Python等语言开发2、Apache/MySQL/PHP各自有什么作用?2.1Apache(httpd)—–像极了饭店前台作用:提供web服务,

    2022年10月16日
    4
  • vue中展示echarts中国地图

    vue中展示echarts中国地图vue 中展示中国地图

    2026年3月26日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号