首页 > 数据库 >【三大锁】悲观锁——mysql悲观锁

【三大锁】悲观锁——mysql悲观锁

时间:2022-08-19 17:48:47浏览次数:69  
标签:悲观 setnx cmd1 三大锁 mysql 10w select

一 三大常用锁

  • 悲观锁
    •   你准备去银行取10w了,跟银行提前打个招呼,有个10w现金谁都别动。(一般只限制写-别人不能取那10w但是能查到银行总体余额,某些场景会限制读)
  • 乐观锁
    •   你准备取10w了,不打招呼,撸起袖子(开始事物,准备好回滚),直接去银行,到了之后,银行告诉你10w在那里,你正好取走(事物提交)。 也有可能去了后,银行说10w没了,那你不取了(事物回滚)
    •       这里面涉及到一个细节,你拿的10w可能是 路人甲 早上取走了最后10w,然后在你到达之前 路人乙 存了10w。 如果你的业务场景是必须要银行的新钱,而不是别人刚存的,那你可以问下银行这个钱是否有人动过(标记操作流水版本号,cas算法的特点)
  • 分布式锁
    •   饭店门口很多顾客(多个访问线程),但是餐桌资源只有空闲的时候才会让人进去。有客户取消或者用餐完毕,某个4人桌就空闲出来了,你就可以去抢占这个4人桌的号(分布式锁),先来先得!(和排号系统还是有点不一样的)

二 实现方式

  • 分布式锁
    •   基本都是拿悲观锁(如 redis: setnx+看门狗+unique_value)
  • 乐观锁
    •   redis的watch
    •       mysql的step1: select step2: update .set. where id = pre_id and version = pre_version 然后判断result是否>0
    •       cas算法基本原理类似,需考虑version
  • 悲观锁
    • reids的setnx + 看门狗
    • 不限制消息发送频率只限制重复发送的场景,可以带上msgid作为setnx的value
    • 怕del错lock,可以把uniq_id 作为setnx的value,然后del之前,get判断uniq_id是否一致! get和del可以通过lua制作成原子命令!
    • mysql的select for update (本文重点)

 

三 mysql悲观锁

用户x下单,系统查询是否有存货,生成订单balabala ( 我们称为process ),存货-1
process的过程中,可能用户y 就下单了,或者比你下单早的用户z 刚好结算到存货-1了,那用户x 直接把库存降到-1了。 虽然可能有数据库unsigned等保护,那如果库存设置的是底货必须是10以上呢?

 所以我们要用到select ..  for update

这玩意就是把select 直接锁住,不让别人增删改(查允许)

如果命中了索引,含主键索引、唯一索引,那么是行锁;否则是表锁;

 cmd1 不commit

 

 

cmd2 会阻塞

 


然后cmd1 commit;则cmd2 success

 

 如果cmd2要update等操作,会命中cmd1的查询结果行(只要包含cmd1的结果,你想想,别人锁住了,你却要动他,虽然你要动1w行,只有其中一行是cmd1的结果,但是就是卡住了,没办法!), 则会阻塞,时间久了会down;未命中cmd1的查询结果行,则没有任何影响。 

cmd1如果resulet为空,那么根据上条结论,也能知道,相当于没锁。

 

 

 

因为name是非索引,这时候直接锁表了,虽然和cmd1的result无关,还是卡住了! 

 

标签:悲观,setnx,cmd1,三大锁,mysql,10w,select
From: https://www.cnblogs.com/bushuwei/p/16602802.html

相关文章

  • Mysql——常用语法
    这里只记录一些mysql语句,用于代替python进行大量的简单性工作。循环创建语句:delimiter$$#声明存储过程的结束符号为$$createprocedureauto_insert1()#相当于声明......
  • mysql运行sql文件报错[ERR] 2006 - MySQL server has gone away [ERR] -- MySQL dump
    原因:在运行数据库脚本文件时报该错,由于mysql对max_allowed_packect 允许最大的数据包的大小有限制解决方法:1.先查看现在允许的最大包大小,单位(字节) select@@max_allow......
  • MySQL事务与锁
    数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。这些问题的本质都是......
  • MySQL视图、触发器、事务
    一、视图1.什么是视图SQL语句的执行结果是一张虚拟表我们可以基于该表做其他操作如果这张虚拟表需要频繁使用那么为了方便可以将虚拟表保存起来保存起来之后就称之为......
  • mysql数据库修改登录密码策略
    showvariableslike'validate_password%';  查看登录密码策略默认策略  1、查看mysql初始的密码策略,    输入语句“SHOWVARIABLESLIKE'validate_p......
  • mysql数据库安装(windows)
    一、下载解压缩文件(免安装版)个人认为配置起来很方便,免去了安装的时各种选择,不用管对应的安装依赖问题。官网下载地址:https://dev.mysql.com/downloads/mysql/二......
  • 在docker内 mysql 中执行sql文件
    通过dockerps查询当前运行的容器,找到mysql容器的iddockerps将项目内的SQL文件拷贝到mysql容器内部的home下的temp文件内sudodockercp/root/sqlfile/mydata.sql8c......
  • Navicat 连接MySQL数据库出现错误:2059 - authentication plugin 'caching_sha2_passwo
    出现这个错误的原因是因为MySQL8.0.19数据库使用的加密方式是:caching_sha2_password,解决: 1 showvariableslike'default_authentication_plugin查看加密信息 2 ......
  • 使用kubersphere 安装有状态服务 MySQL
    kind:StatefulSetapiVersion:apps/v1metadata:name:his-mysqlnamespace:hislabels:app:his-mysqlannotations:kubesphere.io/creator:dev-z......
  • mysql innodb 为什么用B+树作为索引数据结构,而非其他结构
    B树的层数较低,即意味着读取磁盘的次数较少在mysql中一个节点的大小是16K,如果一行数据约1k,其主键为8字节的bigint,那么3层即可容纳约2000万行对比其他结构:hash不体现......