我有两个简单的查询,一个是读取表,一个是更新表。如何在更新查询运行时锁定选择查询的读取。现在在 MySQL InnoDB 中,我注意到写入/更新默认是锁定的,但读取/选择在事务之前获取旧数据。
我尝试在更新查询中使用事务,然后 SELECT ... FOR UPDATE - 在事务之外 - 但它似乎没有成功。另外,出于测试目的,我想知道如何减慢 UPDATE 查询的速度。我遇到了 SLEEP(X),但我不知道如何在更新查询中实现它。
SELECT ... FOR UPDATE
如何让每个查询等待读/写,直到写入完成。
使用READ-COMMITTED事务将查看最新提交的事务。更改,并使用SELECT ... LOCK IN SHARE MODE 将使读取阻塞,直到提交任何未完成的更新。
READ-COMMITTED
SELECT ... LOCK IN SHARE MODE
试试这个。在一个屏幕中,启动事务和更新。不需要 SLEEP(),只是不提交事务。 UPDATE 创建的锁将继续存在,直到您提交为止。
BEGIN; UPDATE MyTable SET something = '1234' WHERE id = 3;
先不要提交。
同时,在第二个屏幕中,将事务隔离设置为读提交事务。无需启动显式事务,因为 InnoDB 查询使用事务,即使它是自动提交的。
SET tx_isolation='READ-COMMITTED'; SELECT * FROM MyTable WHERE id = 3 LOCK IN SHARE MODE; <hangs>
共享模式中的锁使其等待,因为仍有一个由更新创建的未完成的排他锁。
在第一个屏幕中:
COMMIT;
在第二个屏幕中,瞧!阻塞读取将解除阻塞,您可以立即看到 UDPATE 的结果,而无需刷新事务。
使用
READ-COMMITTED
事务将查看最新提交的事务。更改,并使用SELECT ... LOCK IN SHARE MODE
将使读取阻塞,直到提交任何未完成的更新。试试这个。在一个屏幕中,启动事务和更新。不需要 SLEEP(),只是不提交事务。 UPDATE 创建的锁将继续存在,直到您提交为止。
先不要提交。
同时,在第二个屏幕中,将事务隔离设置为读提交事务。无需启动显式事务,因为 InnoDB 查询使用事务,即使它是自动提交的。
共享模式中的锁使其等待,因为仍有一个由更新创建的未完成的排他锁。
在第一个屏幕中:
在第二个屏幕中,瞧!阻塞读取将解除阻塞,您可以立即看到 UDPATE 的结果,而无需刷新事务。