使用场景举例:以MySQL InnoDB为例

商品t_goods表中有一个字段status,status为1代表商品未被下单,status为2代表商品已经被下单,那么我们对某个商品下单时必须确保该商品status为1。假设商品的id为1。

一、如果不采用锁,那么操作方法如下:

//1.查询出商品信息

select status from t_goods where id=1;

//2.根据商品信息生成订单

insert into t_orders (id,goods_id) values (null,1);

//3.修改商品status为2

update t_goods set status=2 where id=1;

上面这种场景在高并发访问的情况下很可能会出现问题。

前面已经提到,只有当goods status为1时才能对该商品下单,上面第一步操作中,查询出来的商品status为1。但是当我们执行第三步Update操作的时候,有可能出现其他人先一步对商品下单把goods status修改为2了,但是我们并不知道数据已经被修改了,这样就可能造成同一个商品被下单2次,使得数据不一致。所以说这种方式是不安全的。

二、使用悲观锁来实现:

在上面的场景中,商品信息从查询出来到修改,中间有一个处理订单的过程,使用悲观锁的原理就是,当我们在查询出goods信息后就把当前的数据锁定,直到我们修改完毕后再解锁。那么在这个过程中,因为goods被锁定了,就不会出现有第三者来对其进行修改了。

注:要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。

我们可以使用命令设置MySQL为非autocommit模式:

set autocommit=0;

设置完autocommit后,我们就可以执行我们的正常业务了。具体如下:

//0.开始事务

begin;/begin work;/start transaction; (三者选一就可以)

//1.查询出商品信息

select status from t_goods where id=1 for update;

//2.根据商品信息生成订单

insert into t_orders (id,goods_id) values (null,1);

//3.修改商品status为2

update t_goods set status=2 where id=1;

//4.提交事务

commit;/commit work;

注:上面的begin/commit为事务的开始和结束,因为在前一步我们关闭了mysql的autocommit,所以需要手动控制事务的提交,在这里就不细表了。

上面的第一步我们执行了一次查询操作:select status from t_goods where id=1 for update;

与普通查询不一样的是,我们使用了select…for update的方式,这样就通过数据库实现了悲观锁。此时在t_goods表中,id为1的那条数据就被我们锁定了,其它的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。

注:需要注意的是,在事务中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。拿上面的实例来说,当我执行select status from t_goods where id=1 for update;后。我在另外的事务中如果再次执行select status from t_goods where id=1 for update;则第二个事务会一直等待第一个事务的提交,此时第二个查询处于阻塞的状态,但是如果我是在第二个事务中执行select status from t_goods where id=1;则能正常查询出数据,不会受第一个事务的影响。

补充:MySQL select…for update的Row Lock与Table Lock

上面我们提到,使用select…for update会把数据给锁住,不过我们需要注意一些锁的级别,MySQL InnoDB默认Row-Level Lock,所以只有「明确」地指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。

mysql实现悲观锁语句_mysql悲观锁总结和实践相关推荐

  1. mysql 悲观锁 共享锁_MySQL 乐观锁 悲观锁 共享锁 排他锁

    乐观锁 乐观锁是逻辑概念上的锁,不是数据库自带的,需要我们自己去实现.乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁 ...

  2. mysql行锁还需要乐观锁吗_mysql行锁、表锁。乐观锁,悲观锁

    锁定用于确保事务完整性和数据库一致性. 锁定可以防止用户读取其他用户正在更改的数据,并防止多个用户同时更改相同的数据. 如果不使用锁定,数据库中的数据可能在逻辑上变得不正确,而针对这些数据进行查询可能 ...

  3. mysql数据库什么情况下会锁表_mysql数据库锁的产生原因及解决办法

    数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性 ...

  4. mysql内置乐观锁吗_mysql 乐观锁详解

    乐观锁: 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制.悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性.但随之而来的就是 ...

  5. delete select语句_MySQL InnoDB锁介绍及不同SQL语句分别加什么样的锁

    作者:iceman1952 链接:https://blog.csdn.net/iceman1952/article/details/85504278 本文中,我们详细介绍MySQL InnoDB存储引 ...

  6. mysql某个表被行锁了_MySQL 行锁和表锁的含义及区别详解

    一.前言 对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统的认识,更详细的需要自行查阅资料,本篇为概括性的总结回答. MySQL常用引擎有MyISAM和Inno ...

  7. mysql BDB支持表锁吗_mysql 表锁问题

    本文转自:http://www.cnblogs.com/itdragon/p/8194622.html MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整 ...

  8. mysql不同锁解释_MySQL 各种锁理解总结

    该文章举例都是基于 InnoDB 可重复读(RR)隔离级别的,mysql 版本 8.0 根据加锁的范围,MySQL 里面的锁大致可以分成全局锁.表级锁和行锁三类 全局锁 全局锁就是对整个数据库实例加锁 ...

  9. mysql间隙锁 打开_MySQL间隙锁问题

    间隙锁(Gap Lock):锁加在不存在的空闲空间,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间. 最近用户反馈说系统老是出现insert时,等待超时了,最后发现是ins ...

最新文章

  1. python数字类型转换函数_Python的数据类型转换函数
  2. android studio安装在其他盘,Android Studio配置移动到D盘(亲测)
  3. spring web参数传递
  4. 天天象棋 残局闯关 第9关
  5. 使用 C# 下载文件的十八般武艺
  6. Coursera自动驾驶课程第4讲:Safety Assurance for Autonomous Vehicles
  7. Python机器学习方向企业面试题(三)
  8. 传统版生产者消费者模式2.0
  9. springboot1.5.4 log4j
  10. 测试环境服务器windows server 2003资源下载
  11. 信息类产品检测培训讲义-EN55022
  12. 【金融量化分析】#BSM formula 的推导(解随机微分方程)
  13. Spring 注解实现原理
  14. Linux学习18-gitlab新建项目提交代码
  15. 【转】奇文共欣赏,疑义相与析:原文转载《电脑维护技巧》(N条举措N条理由)并请大家交流研讨...
  16. ios 常用的30个动画效果
  17. Linux系统安全加固指南(万字长文)
  18. python爬虫数据分析毕业论文_Python 爬虫实操,顺便做了个数据分析
  19. git 创建远程新分支
  20. [原] 手擀寿面祝妈妈生日快乐

热门文章

  1. 时隔二十年,C++又杀回来了!
  2. URAL 2013 Neither shaken nor stirred dfs 模拟
  3. TCP/IP入门详解--业内最佳
  4. 【面向校招】操作系统面经总结
  5. Android自定义华为睡眠,Android 模仿华为健康自定义 计步View
  6. Learning to See before Learning to Act: Visual Pre-training for Manipulation
  7. 如何从光盘启动计算机!
  8. 《R语言与统计分析》-探索性数据分析
  9. CentOS无人值守安装之虚拟机实践
  10. PXE+Kickstart 无人值守装机