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

[经验分享] MySQL8.0新特性——锁读取

[复制链接]

尚未签到

发表于 2018-10-5 08:03:15 | 显示全部楼层 |阅读模式
  MySQL8.0 InnoDB支持 NOWAIT和SKIP LOCKED选项SELECT ... FOR SHARE以及SELECT ... FOR UPDATE锁定读取语句。 NOWAIT如果请求的行被另一个事务锁定,则会立即返回该语句。SKIP LOCKED从结果集中删除锁定的行。
  如果查询数据然后在同一事务中插入或更新相关数据,则常规SELECT 语句不会提供足够的保护。其他事务可以更新或删除您刚查询的相同行。 InnoDB支持两种类型的 锁定读取,提供额外的安全性:
  InnoDB 支持执行 SELECT ... FOR SHARE 和 SELECT ... FOR UPDATE 锁定读语句时,带有NOWAIT 和 SKIP LOCKED 选项。如果请求行已经被其他事务锁定, NOWAIT 会立刻返回结果。 SKIP LOCKED 将锁定的行从结果中移除。
  官方文档:
  https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html#innodb-locking-reads-nowait-skip-locked
  1、SELECT ... FOR SHARE:
  在读取的任何行上设置共享模式锁定。其他会话可以读取行,但在事务提交之前无法修改它们。如果这些行中的任何行已被另一个尚未提交的事务更改,则查询将等待该事务结束,然后使用最新值。
  注意:
  SELECT ... FOR SHARE是替代SELECT ... LOCK IN SHARE MODE,但 LOCK IN SHARE MODE仍可用于向后兼容。
  2、SELECT ... FOR UPDATE:
  对于搜索遇到的索引记录,锁定行和任何关联的索引条目,就像您UPDATE为这些行发出 语句一样。阻止其他事务更新这些行,执行SELECT ... FOR SHARE或从某些事务隔离级别读取数据。一致性读取将忽略在读取视图中存在的记录上设置的任何锁定。(旧版本的记录无法锁定;它们是通过在记录的内存副本上应用撤消日志来重建的 。)
  注意:
  ①:提交或回滚事务时,将释放 由设置FOR SHARE和FOR UPDATE查询设置的所有锁。
  ②:只有在禁用自动提交时(通过使用START TRANSACTION或通过设置 autocommit为0 开始事务处理),才能锁定读取 。
  除非在子查询中指定了锁定读取子句,否则外部语句中的锁定读取子句不会锁定嵌套子查询中的表行。例如,以下语句不会锁定表中的行 t2:
  SELECT * FROM t1 WHERE c1 = (SELECT c1 FROM t2) FOR UPDATE;
  要锁定表中的行,t2请在子查询中添加一个锁定读取子句:
  SELECT * FROM t1 WHERE c1 = (SELECT c1 FROM t2 FOR UPDATE) FOR UPDATE;
  3、使用NOWAIT和SKIP LOCKED锁定读取并发
  如果行被事务锁定 ,则请求相同锁定行的事务SELECT ... FOR UPDATE或SELECT ... FOR SHARE事务必须等到阻塞事务释放行锁。此行为可防止事务更新或删除由其他事务查询以进行更新的行。但是,如果您希望在请求的行被锁定时立即返回查询,或者从结果集中排除锁定的行是可接受的,则无需等待释放行锁定。
  为了避免等待其他事务释放行锁, NO WAIT并且SKIP LOCKED 选项可以与 read语句一起使用SELECT ... FOR UPDATE或SELECT ... FOR SHARE锁定。
  ①:NOWAIT:   使用NOWAIT永不等待获取行锁定的锁定读取。查询立即执行,如果请求的行被锁定,则失败并显示错误。
  ②:SKIP LOCKED:  使用SKIP LOCKED 永不等待获取行锁定的锁定读取。查询立即执行,从结果集中删除锁定的行。
  注意:
  ①:跳过锁定行的查询会返回数据的不一致视图。SKIP LOCKED因此不适合一般交易工作。但是,当多个会话访问同一个类似队列的表时,它可用于避免锁争用。
  ②:NO WAIT和SKIP LOCKED 仅适用于行级锁。
  以下示例演示NOWAIT 和SKIP LOCKED。会话1启动一个事务,该事务对单个记录执行行锁定。会话2尝试使用该NOWAIT选项对同一记录进行锁定读取 。由于请求的行被会话1锁定,因此锁定读取会立即返回错误。在会话3中,锁定读取SKIP LOCKED返回请求的行,但会话1锁定的行除外。
  # Session 1:
  mysql> CREATE TABLE t (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
  mysql> INSERT INTO t (i) VALUES(1),(2),(3);
  mysql> START TRANSACTION;
  mysql> SELECT * FROM t WHERE i = 2 FOR UPDATE;
  +---+
  | i |
  +---+
  | 2 |
  +---+
  # Session 2:
  mysql> START TRANSACTION;
  mysql> SELECT * FROM t WHERE i = 2 FOR UPDATE NOWAIT;
  ERROR 3572 (HY000): Do not wait for lock.
  # Session 3:
  mysql> START TRANSACTION;
  mysql> SELECT * FROM t FOR UPDATE SKIP LOCKED;
  +---+
  | i |
  +---+
  | 1 |
  | 3 |
  +---+


运维网声明 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-612439-1-1.html 上篇帖子: MySQL/MariaDB基础及简单SQL语句 下篇帖子: 安装配置Mysql
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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