从MySQL 文档中获取的共享模式中选择锁定的示例:
作为锁定读取有用的情况的示例,假设您想将新行插入到子表中,并确保子行在父表中具有父行。假设你使用一致性读来读取表parent,并且确实看到了表中要插入的子行的父行。您可以安全地将子行插入到表子中吗?不,因为其他会话可能会在您不知情的情况下同时从表 parent 中删除父行。
解决方案是使用 LOCK IN SHARE MODE 在锁定模式下执行 SELECT:
<?php
DB::query("start transaction");
$q = DB::query("SELECT parentID FROM parent WHERE NAME = 'Jones'
LOCK IN SHARE MODE;");
if( count($q) === 1)
DB::query("insert into child set parentName = 'Jones', ... other data");
DB::query("commit;");
?>
SELECT ... LOCK IN SHARE MODE 在读取的任何行上设置共享模式锁。其他会话可以读取这些行,但在您的事务提交之前不能修改它们。
如果在我们执行查询启动事务之后代码执行失败(php 错误、操作系统错误、电源故障……)会发生什么;select parentID from parent where name = 'Jones' lock in share mode; . 行保持锁定更新和删除多长时间?我想确保即使执行失败,该行也不会保持锁定(假设 PHP 失败但 MySQL 仍在运行)。MySQL 如何处理这种情况。我想在最坏的情况下超时发生是这样的:
ERROR 1205 (HY000): 超过锁定等待超时;尝试重启事务
和 MySQL 解锁锁定的行。或者有没有更好的机制。