微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PHP – MySQL行级锁定示例

我已经看过许多帖子,解释了Select FOR UPDATE的用法以及如何锁定行,但是我无法找到任何解释当代码尝试读取被锁定的行时发生的情况.

例如.假设我使用以下内容

$con->autocommit(FALSE);
$ps = $con->prepare( "SELECT 1 FROM event WHERE row_id = 100 FOR UPDATE");
$ps->execute();
...
//do something if lock successful
...
$MysqLi->commit();

在这种情况下,我如何确定我的锁是否成功?行已被锁定时处理场景的最佳方法是什么?

对不起,如果在某处描述,但我似乎找到的只是“快乐路径”的解释.

解决方法:

In this case, how do I determine if my lock was successful? What is the best way to handle a scenario when the row is locked already?

如果您尝试锁定的行已被锁定 – MysqL服务器将不会返回此行的任何响应.它会等待,直到锁定事务被提交或回滚.

(显然:如果已经删除了行,那么SELECT将返回一个空结果集并且不会锁定任何内容)

之后,它将返回最新值,由持有锁的事务提交.

常规选择语句不关心锁定并返回当前值,忽略存在未更改的更改.

因此,换句话说:只有在锁定成功时才会执行您的代码. (其他人等待,直到先前的锁定被释放)

注意,使用FOR UPDATE也会阻止任何事务SELECTS锁定时间 – 如果你不想这样,你应该使用LOCK IN SHARE MODE.这将允许事务选择继续使用当前值,而只是阻止任何更新或删除语句.

²查询将在innodb_lock_wait_timeout http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout定义的时间后返回错误
然后它将返回ERROR 1205(HY000):超过锁定等待超时;尝试重新启动事务

换句话说:这就是你尝试获取锁定失败的地方.

Sidenode:这种锁定只适用于确保数据完整性. (即,在插入引用此行的内容时,不会删除任何引用的行).

一旦锁定被释放,任何被阻止(或更好地调用它被延迟)的删除语句将被执行,可能会删除您刚插入的行,因为您刚刚持有锁的行上的级联以确保完整性.

如果你想创建一个系统来避免2个用户同时修改相同的数据,你应该在应用程序级别执行此操作并查看悲观的vs乐观锁定approches,因为保持事务运行很长时间不是一个好主意.一段的时间. (我认为在PHP中,您的数据库连接无论如何都会在每次请求后自动关闭,导致对任何正在运行的事务进行隐式提交)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐