如果在共享模式下选择锁定后程序执行中止,则行锁定

时间:2013-10-24 10:39:55

标签: mysql locking simultaneous

MySQL documentation获取的共享模式中的选择锁定示例:

作为锁定读取有用的情况的示例,假设您要将新行插入表子项,并确保子行在表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在任何读取的行上设置共享模式锁定。其他会话可以读取行,但在事务提交之前无法修改它们。

在我们执行查询 start transaction之后,如果代码执行失败(php错误,操作系统错误,电源故障......)会发生什么?从父级中选择parentID,其中name ='Jones' 锁定共享模式; 。行保持锁定多长时间以进行更新和删除?我想确保即使执行失败,该行也不会保持锁定状态(让我们说PHP失败但MySQL仍在运行)。 MySQL如何处理这种情况。我想在最坏的情况下,超时发生如下:

  

ERROR 1205(HY000):超出锁定等待超时;尝试重新启动交易

和MySQL解锁锁定的行。或者是否有更好的机制。

1 个答案:

答案 0 :(得分:1)

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

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