gpt4 book ai didi

PHP - MySQL 行级锁定示例

转载 作者:可可西里 更新时间:2023-11-01 07:58:46 25 4
gpt4 key购买 nike

我看过很多解释 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 将返回一个空结果集并且不会锁定任何内容)

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

常规 Select 语句不会关心锁定并返回当前 值,忽略有未提交的更改。

因此,换句话说:您的代码只会在锁定成功时执行。 (否则等待²直到先前的锁被释放)

请注意,使用 FOR UPDATE 也会在锁定期间阻止任何事务性 SELECTS - 如果您不想这样做,您应该使用 LOCK IN共享模式 代替。这将允许事务选择继续处理当前 值,同时阻止任何更新或删除语句。

² 在 innodb_lock_wait_timeout http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout 定义的时间之后,查询将返回错误。然后它将返回 ERROR 1205 (HY000): Lock wait timeout exceeded;尝试重启交易

换句话说:这就是您尝试获取锁失败的地方。


Sidenode:这种锁定只是适合确保数据完整性。 (即,当您插入引用该行的内容时,不会删除任何引用行)。

一旦锁被释放,任何阻塞的(或更好地称其为延迟)删除语句将被执行,可能会删除您刚刚插入的行,因为行上的 Cascading您刚刚持有锁以确保完整性。

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

关于PHP - MySQL 行级锁定示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26636224/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com