0

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 解锁锁定的行。或者有没有更好的机制。

4

1 回答 1

1

如果错误导致连接关闭 - MySql 回滚整个事务,并释放所有锁。
如果连接没有关闭(电源故障,应用程序挂起等) - MySql 将在wait_timeoutinteractive_timeout变量定义的时间后关闭连接。关闭连接会导致活动事务回滚,并释放所有锁。

wait_timeout --> http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout
interactive_timeout --> http://dev.mysql.com/doc/refman/5.6 /en/server-system-variables.html#sysvar_interactive_timeout

于 2013-10-24T13:09:23.297 回答