简体   繁体   English

Mysql InnoDB从读取行锁定

[英]Mysql InnoDB row locking from read

I have read mysql documentation and maybe I just don't understand it all. 我已经阅读过mysql文档,也许我只是不明白这一切。 What I'm looking for is the row locking from reading for other sessions. 我正在寻找的是读取其他会话的行锁定 While the row is locked I would like the other sessions to wait until the lock is released. 当行被锁定时,我希望其他会话等到锁被释放。 I don't want the other sessions to read from snapshot! 我不希望其他会话从快照中读取! they must wait until release is made! 他们必须等到发布!

What I would like to get is exactly the same as the following example but for a single row instead of whole table lock: 我想得到的是与以下示例完全相同,但对于单行而不是整个表锁:

START TRANSACTION
LOCK TABLES table1 WRITE
SELECT * FROM table1 WHERE id = 40912
UPDATE table1 SET column1 = 'value1' WHERE id = 40912
UNLOCK TABLES
COMMIT

Thank you in advance! 先感谢您!

The answer from Elena Sharovar is a way to do it, but perhaps doesn't fully explain what's required. Elena Sharovar的答案是一种方法,但也许并不能完全解释所需要的。 Every process that's going to perform the SELECT needs to use GET_LOCK with the same string. 将要执行SELECT的每个进程都需要使用具有相同字符串的GET_LOCK。 If they do, MySQL will automatically wait (up to the number of seconds specified) to return a result until the other thread releases the lock. 如果他们这样做,MySQL将自动等待(最多指定的秒数)返回结果,直到另一个线程释放锁定。

Here's what happens, with time proceeding from top to bottom: 这是随着时间从上到下发生的事情:

          THREAD 1                                 THREAD 2
DO GET_LOCK("table1.40912", 30)
SELECT * FROM table1 WHERE id=40912     DO GET_LOCK("table1.40912", 30)
[UPDATE query]                          [automatically waits]
[UPDATE query]                          [automatically waits]
DO RELEASE_LOCK("table1.40912")         [lock finally obtained, query terminates]
                                        SELECT * FROM table1 WHERE id=40912

I did not try to do it yet, but it's possible using MySQL functions GET_LOCK(str,timeout) and RELEASE_LOCK(str). 我还没有尝试这样做,但可以使用MySQL函数GET_LOCK(str,timeout)和RELEASE_LOCK(str)。 Here "str" is any string identificating your lock. 这里“str”是识别你的锁的任何字符串。

mysql_query('DO GET_LOCK("table1.40912", 60)')
mysql_query('SELECT * FROM table1 WHERE id = 40912')
mysql_query('UPDATE table1 SET column1 = 'value1' WHERE id = 40912')
mysql_query('DO RELEASE_LOCK("table1.40912")') 

The best idea I have for this interesting problem (how to force MySQL to not read a snapshot, even if the snapshot is consistent) would be to read everything using "FOR UPDATE", as in "SELECT FOR UPDATE #select-clause#". 我对这个有趣的问题(如何强制MySQL不读取快照,即使快照是一致的)的最佳想法是使用“FOR UPDATE”读取所有内容,如“SELECT FOR UPDATE#select-clause#” 。

However, it is very important that these selects find the records using very narrow indexes, meaning they lock what they read. 但是,这些选择使用非常窄的索引查找记录非常重要,这意味着它们会锁定它们读取的内容。 Having a SELECT running wild via a full table scan or even a USING WHERE (in EXPLAIN statements) would be bad, long locking times of large areas of the table could lead to potentially long reaction times. 让SELECT通过全表扫描或甚至USING WHERE(在EXPLAIN语句中)运行会很糟糕,表的大区域的长锁定时间可能导致可能长的响应时间。

I'd suggest you test it in your database abstraction layer. 我建议你在数据库抽象层中测试它。

You can read all about this mechanism in the isolation documentation . 您可以在隔离文档中阅读有关此机制的所有信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM