mysql中使用 NOWAIT 和 SKIP LOCKED 实现锁定读取并发性

NOWAIT 和 SKIP LOCKED 是用于 SELECT ... FOR UPDATE 或 SELECT ... FOR SHARE 锁定读取语句的选项,用于实现并发读取锁定。

当一个事务锁定一行时,如果另一个事务请求相同被锁定的行的 SELECT ... FOR UPDATE 或 SELECT ... FOR SHARE 语句,它必须等待阻塞事务释放行锁。这种行为防止其他事务更新或删除被其他事务查询的行。然而,如果你希望在请求的行被锁定时立即返回查询结果,或者如果从结果集中排除已被锁定的行可接受的话,则不需要等待行锁释放。

为了避免等待其他事务释放行锁,可以使用 NOWAIT 和 SKIP LOCKED 选项与 SELECT ... FOR UPDATE 或 SELECT ... FOR SHARE 锁定读取语句。

  • NOWAIT:使用 NOWAIT 的锁定读取永远不会等待获取行锁。该查询立即执行,如果请求的行被锁定,则失败并返回错误信息。
  • SKIP LOCKED:使用 SKIP LOCKED 的锁定读取永远不会等待获取行锁。该查询立即执行,从结果集中移除已被锁定的行。

注意:

跳过已被锁定的行的查询返回的是数据的不一致视图。因此,SKIP LOCKED 不适用于常规的事务工作。然而,当多个会话访问同一个类似队列的表时,可以使用 SKIP LOCKED 来避免锁竞争。

NOWAIT 和 SKIP LOCKED 仅适用于行级锁。

使用 NOWAIT 或 SKIP LOCKED 的语句不适用于基于语句的复制。

以下示例演示了 NOWAIT 和 SKIP LOCKED 的用法。会话1开始一个事务,在单个记录上获取行锁。会话2尝试使用 NOWAIT 选项对相同记录进行锁定读取。由于请求的行被会话1锁定,锁定读取立即返回错误。在会话3中,使用 SKIP LOCKED 的锁定读取返回了除了会话1锁定的行之外的请求行。

# 会话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 |
+---+

# 会话2:

mysql> START TRANSACTION;

mysql> SELECT * FROM t WHERE i = 2 FOR UPDATE NOWAIT;
ERROR 3572 (HY000): Do not wait for lock.

# 会话3:

mysql> START TRANSACTION;

mysql> SELECT * FROM t FOR UPDATE SKIP LOCKED;
+---+
| i |
+---+
| 1 |
| 3 |
+---+

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值