设为首页 收藏本站
查看: 532|回复: 0

[经验分享] mysql中的get_lock锁机制解析

[复制链接]

尚未签到

发表于 2018-10-6 11:12:29 | 显示全部楼层 |阅读模式
  mysql中的get_lock锁机制解析
  mysql> SELECT GET_LOCK('MySQL', 10) ; 返回结果为1,说明成功得到锁
  +-----------------+
  | ci_session_lock |
  +-----------------+
  |               1 |
  +-----------------+
  1 row in set (0.00 sec)

  mysql>select>  +----------------------------------------------------------+

  |>  +----------------------------------------------------------+
  |                                                        1 |
  +----------------------------------------------------------+
  1 row in set (0.00 sec)
  mysql> SELECT IS_USED_LOCK('MySQL') ; 返回结果为当前连接ID,表示名称为'MySQL'的锁正在被使用。
  +-----------------+
  | ci_session_lock |
  +-----------------+
  |            8 |
  +-----------------+
  1 row in set (0.00 sec)
  mysql> SELECT IS_FREE_LOCK('MySQL') ; 返回结果为0,说明名称为'MySQL'的锁正在被使用。
  +-----------------+
  | ci_session_lock |
  +-----------------+
  |               0 |
  +-----------------+
  1 row in set (0.00 sec)
  创建表:
  create table test_lock(
  id int,
  name varchar(50),
  address varchar(50)
  );
  insert into test_lock values(1,'tt','aaaaaaaaaaaaaaaaaaaa');
  A1:
  select get_lock('key_lock', 100);

  update test_lock set name = 'tt2', address = 'aaaaaaaaaaaaaaaaaaaa' where>
  select>  A2:
  select get_lock('key_lock', 100);

  update test_lock set name = 'tt', address = 'bbbbbbbbbbbbbbbbbbbbbbb' where>
  select>  执行A1的第一条语句后执行A2的第一条语句会发现一直卡在那里,直接执行了A1的最后一条语句(或过期或断线)为止才能继续执行A2的语句。
  如果按上面的顺序分别执行了A1和A2中的语句,则最后表中的数据是按A2的第二语句更新那样的显示,这种结果当然不是我们想要的,实际项目中,应该是先查出来id为1的数据,把某列更新的值set进去(针对Java),再执行更新,这样所有的更新结果都是正确的。

  •   优缺点分析
      (1)这种方式对于更新所有列比较有效,但是得把查询的语句也放在锁内执行;
      (2)这种方式当客户端无故断线了会自动释放锁,比较好,不像redis锁那样,如果加完锁断了,那么锁一直在;
      (3)这种方式是针对锁内的所有操作加锁,并不针对特定表或特定行,所以使用了同一个Key的锁但不同的操作都会共用一把锁,会导致效率低下;
      (4)如果查询语句放在锁之前,则数据可能是旧的,更新之后会把查询之后更新之前别的客户端更新的数据覆盖掉;
  • 举个Java例子的伪代码  A1客户端:
  execute("select get_lock('key_lock', 100)");
  User user = queryUser(1);
  user.setName("tt1");
  updateUser(user);

  execute("select>  A2客户端:
  execute("select get_lock('key_lock', 100)");
  User user = queryUser(1);
  user.setAddress("bbbbbbbbbbbbbb");
  updateUser(user);

  execute("select>  按照以上这种方式操作则两条更新语句都是正确的,最后的结果应该是
  name = ‘tt1’,
  address = ‘bbbbbbbbbbbbbb’


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-613628-1-1.html 上篇帖子: Mysql二种安装 下篇帖子: 获取mysql所有表中的字段
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表