【问题标题】:MySQL Read vs Write LockMySQL 读与写锁
【发布时间】:2021-10-11 00:57:11
【问题描述】:

我希望客户端会话锁定一个表,以便它可以继续读取和写入该表。同时其他客户端会话应该只能从表中读取。一旦锁被移除,那么所有客户端会话都应该被允许读取和写入表。此外,一旦锁定被删除,所有在锁定时尝试写入表的客户端会话都应该执行。我不希望在锁定期间尝试插入时引发任何错误。

我知道读锁不起作用,因为创建锁的客户端会话在锁存在时无法写入表。此外,写锁也不起作用,因为其他客户端会话无法从表中读取。我有什么办法可以做到这一点?

【问题讨论】:

  • 锁定表很少见。写锁通常意味着排他锁,这意味着只有给定的连接才能访问表。在这种情况下,您可能必须实现应用程序级锁定。
  • 您没有充分解释为什么标准BEGIN; ((do read FOR UPDATE ... writes)) COMMIT; 是不够的。注意FOR UPDATE
  • @RickJames BEGIN; ((do read FOR UPDATE ... writes)) COMMIT; 似乎是一个不错的解决方案,只要其他客户端可以继续从表中读取。听起来他们可以根据比尔。

标签: mysql locking


【解决方案1】:

由于您在问题中所述的原因,您不能使用 LOCK TABLES 语句对表锁执行此操作。

您可以通过在表的所有行上创建行锁来做到这一点:

SELECT COUNT(*) FROM mytable FOR UPDATE;

在您提交事务之前,行锁会阻止任何其他会话写入,但只要不尝试使用锁定读取查询,它们就可以读取。同时,您可以读取或写入表,因为您已经锁定了所有行。

另一种解决方案是获取全局锁,但不要使用LOCK TABLES。我编写了系统,所有参与的客户端都需要在写入表之前使用GET_LOCK() function 获取锁。但如果他们只需要阅读,他们就跳过对该锁的请求。这可行,但需要所有客户端都包含支持相同访问策略的代码。

【讨论】:

  • BEGIN; SELECT COUNT(*) FROM mytable FOR UPDATE; COMMIT; 听起来可能是我正在寻找的,因为其他客户端仍然可以从表中读取。
猜你喜欢
  • 1970-01-01
  • 2012-08-24
  • 2011-01-25
  • 2011-12-04
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 2021-06-24
  • 2014-12-25
相关资源
最近更新 更多