选择此选项以更新MySQL中的整个表,而不是逐行更新

选择此选项以更新MySQL中的整个表,而不是逐行更新,mysql,select,transactions,sql-update,Mysql,Select,Transactions,Sql Update,我将有多个客户端将数据输入数据库,我必须确保事务不会混淆 我在文档中读到启动事务和选择。。。对于更新锁定它读取的每一行: 精选的。。。对于更新,读取最新的可用数据,在其读取的每一行上设置独占锁。因此,它设置的锁与搜索到的SQL更新在行上设置的锁相同 看 因此,我登录了一个客户端并键入以下语句: START TRANSACTION; SELECT * FROM productMacAddress WHERE status='free' limit 8 FOR UPDATE; 暂停此处以获取第二个

我将有多个客户端将数据输入数据库,我必须确保事务不会混淆

我在文档中读到
启动事务
选择。。。对于更新
锁定它读取的每一行:

精选的。。。对于更新,读取最新的可用数据,在其读取的每一行上设置独占锁。因此,它设置的锁与搜索到的SQL更新在行上设置的锁相同

因此,我登录了一个客户端并键入以下语句:

START TRANSACTION;
SELECT * FROM productMacAddress WHERE status='free' limit 8 FOR UPDATE;
暂停此处以获取第二个客户端条目

在另一个客户端中,我键入:

START TRANSACTION;
SELECT * FROM productMacAddress WHERE status='free' limit 4 FOR UPDATE;
UPDATE productMacAddress SET status='testing2' WHERE status='free' LIMIT 4;
COMMIT;
但是在第一个客户端完全完成之前,我无法从表中选择任何内容。为什么会这样?文档说明它应该逐行锁定,特别是因为I
LIMIT 8


提前感谢。

InnoDB表的默认隔离级别为可重复读取。当此隔离级别处于活动状态时,我们将获得以下行为(引用自:):

对于锁定读取(选择更新或共享模式下锁定), UPDATE和DELETE语句,锁定取决于 语句使用具有唯一搜索条件的唯一索引,或 范围类型搜索条件。对于具有唯一搜索的唯一索引 条件下,InnoDB只锁定找到的索引记录,而不锁定间隙 在它之前。对于其他搜索条件,InnoDB会锁定索引范围 扫描,使用间隙锁或下一个键(间隙加索引记录)锁定 阻止其他会话插入该范围覆盖的间隙

换句话说:您能尝试在SELECT的WHERE条件下使用主键吗?因此,例如,而不是:

START TRANSACTION;
SELECT * FROM productMacAddress WHERE status='free' limit 8 FOR UPDATE;
尝试:


以防id是主键。任何其他具有唯一索引的列也可以使用。当在WHERE子句中使用非唯一列时,InnoDB将锁定一系列行。

有一种稍微复杂的情况:当“SELECT FOR UPDATE”后面跟着WHERE语句,例如:“WHERE(indexed_key=value1或indexed_key=value2)”,InnoDB将再次锁定整个表,而不是这两行。为什么呢?
START TRANSACTION;
SELECT * FROM productMacAddress WHERE status='free' limit 8 FOR UPDATE;
START TRANSACTION;
SELECT * FROM productMacAddress WHERE id=10 FOR UPDATE;