1.乐观锁:乐观锁的实现完全是逻辑的,不需要数据库提供特殊的支持,一般的做法是在需要锁的数据上增加一个版本号

    public function lock(){//获取id=1该数据行的版本$version = Db::table('test')->where('id',1)->value('version');//TO DO...(执行其他业务逻辑)//如果最后取锁失败,可能需要回撤这些业务逻辑,所以乐观锁适合数据不那么频繁被更新的场景//更新数据$data['user_id'] = 100;$data['user_name'] = 'guangdong';$data['version'] = $version + 1;//更新条件:id=1 version=$version//如果没有被其他业务更新,版本号是不会变化的,更新操作可以完成;否则更新失败$affectRows = Db::table('test')->where(['id'=>1,'version'=>$version])->update($data);if($affectRows !== false){$result['code'] = 1;$result['msg'] = '乐观锁取锁成功';}else{$result['code'] = 2;$result['msg'] = '乐观锁取锁失败';//TO DO...(回撤其他业务逻辑)
        }return json($result);}

2.悲观锁:悲观锁的实现需要数据库提供支持,开启事务并调用数据库的相关语句 lock in share mode 或者 for update,即共享锁和排他锁两种表示形式
2.1共享锁:如select ... lock in share mode,此时给数据加了一把锁,对其只能进行读操作,其他事务可以对该数据再加共享锁,但不能再加排他锁,需要等待当前事务共享锁的释放
2.2排他锁:如select ... for update,给数据加了一把锁,只有当前事务可以对其进行读和写操作,其他事务不能读写也不能加锁,需要等待当前事务排他锁的释放
2.3注意 :   
  a.加锁时所有扫描过的行都会被锁上,因此使用悲观锁务必确定走了索引,而不是全表扫描,全表扫描相当于锁表操作
  b.update、delete、insert操作会自动给语句加排他锁,所以在这三种语句后面不能加lock in share mode或是for update,否则语法会报错
  c.事务提交、进程结束、进程中断都会自动释放锁
  d.无论加共享锁还是排他锁都不影响普通select查询,因为普通查询时不会给语句加锁
2.4测试:打开两个浏览器窗口,窗口1执行add_lock方法,窗口2执行test_lock方法

   //当前事务:对id=1的数据加锁public function add_lock(){Db::startTrans();$result = Db::query('SELECT * FROM `test` WHERE id=1 LOCK IN SHARE MODE');  //对主键为1的数据加共享锁//$result = Db::query('SELECT * FROM `test` WHERE id=1 FOR UPDATE');        //对主键为1的数据加排他锁sleep(150);//阻断锁的释放}

    //其他进程:对id=1的数据增删改查public function test_lock(){//查询$result = Db::query('SELECT * FROM `test` WHERE id=1');                               //普通查询//$result = Db::query('SELECT * FROM `test` WHERE id=1 LOCK IN SHARE MODE');          //共享锁查询//$result = Db::query('SELECT * FROM `test` WHERE id=1 FOR UPDATE');                  //排他锁查询//更新$result = Db::query('UPDATE `test` SET version=2 WHERE id=1');                        //普通更新//$result = Db::query('UPDATE `test` SET version=2 WHERE id=1 LOCK IN SHARE MODE');   //共享锁更新//$result = Db::query('UPDATE `test` SET version=2 WHERE id=1 FOR UPDATE');           //排他锁更新//删除$result = Db::query('DELETE FROM `test` WHERE id=1');                                 //普通删除//$result = Db::query('DELETE FROM `test` WHERE id=1 LOCK IN SHARE MODE');            //共享锁删除//$result = Db::query('DELETE FROM `test` WHERE id=1 FOR UPDATE');                    //排他锁删除//插入(第一个1是主键)$result = Db::query('INSERT INTO `test` VALUES (1,6,6,6,6,6,6)');                     //普通插入//$result = Db::query('INSERT INTO `test` VALUES (1,6,6,6,6,6,6) LOCK IN SHARE MODE');//共享锁插入//$result = Db::query('INSERT INTO `test` VALUES (1,6,6,6,6,6,6) FOR UPDATE');        //排他锁插入
dump($result);}

    测试结果:ok表示可以进行操作;no表示需要等待锁的释放,否则无法进行操作;error表示语法报错
    加共享锁后:  普通查询ok       共享锁查询ok         排他锁查询no普通更新no       共享锁更新error      排他锁更新error普通删除no       共享锁删除error      排他锁删除error普通插入error    共享锁插入error      排他锁插入error加排他锁后:  普通查询ok       共享锁查询no         排他锁查询no普通更新no       共享锁更新error      排他锁更新error普通删除no       共享锁删除error      排他锁删除error普通插入error    共享锁插入error      排他锁插入error

3.表锁:LOCK TABLE为当前线程锁定表。UNLOCK TABLES释放被当前线程持有的任何锁。如果一个线程获得在一个表上的一个READ锁,该线程和所有其他线程只能从表中读。如果一个线程获得一个表上的一个WRITE锁,那么只有持锁的线程可以从表中读写,其他线程被阻止。

    LOCK TABLE [table] [READ|WRITE];.........UNLOCK TABLES;

4.行锁:即共享锁和排他锁

转载于:https://www.cnblogs.com/xincanzhe/p/10411107.html

理解乐观锁、悲观锁、共享锁、排他锁、表锁、行锁相关推荐

  1. mysql某个表被行锁了_MySQL中的锁(表锁、行锁)

    锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...

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

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

  3. java mysql 行锁_Java如何实现对Mysql数据库的行锁?

    行锁 mysql实现行级锁的两大前提就是,innodb引擎并且开启事务.由于MySQL/InnoDB的加锁分析,一般日常中使用方式为: select .... from table where ... ...

  4. mysql某个表被行锁了_一文搞懂MySQL行锁、表锁、间隙锁详解

    准备工作 创建表 tb_innodb_lock drop table if exists test_innodb_lock; CREATE TABLE test_innodb_lock ( a INT ...

  5. MySQL数据库锁构建_MySQL数据库InnoDB存储引擎中的锁机制

    00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是其中的一种机制.我们用商场的试衣间来做一个比喻.试衣间供许多消费者使用.因此可能有 ...

  6. Java锁详解:“独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁+线程锁”

    在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 线程锁 乐观锁 VS 悲 ...

  7. 最全MySQL锁讲解:页锁、共享锁、行锁、表锁、悲观锁、乐观锁

    我们在操作数据库的时候,可能会由于并发问题而引起的数据的不一致性(数据冲突),如何保证数据并发访问的一致性.有效性,是所有数据库必须解决的一个问题,锁的冲突也是影响数据库并发访问性能的一个重要因素,从 ...

  8. [精选]MySQL的各种锁(表锁,行锁,悲观锁,乐观锁,间隙锁,死锁)

    不少人在开发的时候,应该很少会注意到这些锁的问题,也很少会给程序加锁(除了库存这些对数量准确性要求极高的情况下),即使我们不会这些锁知识,我们的程序在一般情况下还是可以跑得好好的.因为数据库隐式帮我们 ...

  9. mysql的锁机制(读锁,写锁,表锁,行锁,悲观锁,乐观锁,间隙锁)

    读锁和写锁 介绍 MyISAM表锁中的读锁和写锁 读锁(共享锁S): 对同一个数据,多个读操作可以同时进行,互不干扰.加锁的会话只能对此表进行读操作,其他会话也只能进行读操作.MyISAM的读默认是加 ...

  10. MySQL:行锁、表锁、乐观锁、悲观锁、读锁、写锁

    1.锁的分类 1.1从对数据操作的类型来分 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响. 结论1: --如果某一个会话 对A表加了read锁,则 该会话 可以对A表进行读操作 ...

最新文章

  1. 史上最全 | 数据分析技能详细拆解,一张图覆盖全流程知识细节和资源推荐(附下载)...
  2. 10-Python与设计模式--享元模式
  3. 成本要素区分成本中心
  4. python中的__str__ __name__ 和__call__方法
  5. ue编辑器拖拽上传图片_Typora + PicGo打造超好用的Markdown编辑器
  6. YBTOJ:向量问题(线段树分治、凸包)
  7. html ace编辑器,Tiny-editor
  8. 中小学生Python课应该学什么
  9. 【转载】接口和抽象类的区别 --相信你看完不会再混淆了
  10. python 3d重建_三维人脸重建(一)——Python读取obj文件
  11. 用css 添加手状样式,鼠标移上去变小手
  12. 用python批量导入阿里云安全组规则
  13. 等待任务执行完成时,界面上转圈圈,不让用户操作软件
  14. 电脑端同时登陆两个微信(非网页版)
  15. python绘图坐横坐标轴显示
  16. lte tm模式_LTE 的传输模式及各自的区别和作用
  17. let 连续复制_要在Word中使用“格式刷”对同一个格式进行多次复制时,应先用鼠标()。...
  18. python+tkinter创作老黄历,窗口化显示:择吉,五行,财福喜神
  19. 用Arduino读取HX711应变片专用模块
  20. 谷歌股票“打折”卖,一股换20股

热门文章

  1. 编程基本功:带着本子却不记录,你以为听懂了记住了,不可能的
  2. 研究了EXCEL的行高问题
  3. SVN遗漏so文件的解决办法
  4. NWT失败反省:谁给汝之权力,竟然敢要吾走人?
  5. 积累的历年博客终于发完了
  6. 诺基亚再做手机,没有机会
  7. LINUX查看文件系统
  8. 建议不要使用Android studio的SVN功能
  9. python字符串偏移量_字符串掩码和带正则表达式的偏移量
  10. c++字符串相等比较 char* char[] string