升级到mysql 5.7之后GET_LOCK
停止工作,因为它在mysql 5.5上使用并且正如我预期的那样。我知道5.7中GET_LOCK
的变化。正如here所述。
当我从cmd行执行相同的脚本两次 - 其间有小暂停 - 它按预期工作:第一个获取锁定,第二个获取锁定。
当我通过浏览器两次执行相同的php脚本时 - 两者之间有小暂停 - 两者都返回它们成功获得锁定。这个结果不是我所期望的,它与5.5版和我对5.7文档中描述的GET_LOCK
的理解不同。
这是示例脚本locktest.php
:
<?php
$host = 'localhost';
$db = 'enter_your_db';
$user = 'enter_your_username';
$pass = 'enter_your_password';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_PERSISTENT => false
];
$pdo = new PDO($dsn, $user, $pass, $opt);
echo "pid=(".getmypid().")\n";
$stmt = $pdo->query('SELECT connection_id() as connid');
$row = $stmt->fetch();
echo "mysql connection id =(".$row['connid'].")\n";
$stmt = $pdo->query('SELECT GET_LOCK("foobar", 2)');
$row = $stmt->fetch();
var_dump($row);
echo "\n\n";
sleep(10);
当这个脚本从cmd行运行时 - 我得到了我的期望: 从一个终端运行php -q locktest.php。然后立即从另一个终端窗口。
第一个将返回:
pid=(18378)
mysql connection id =(71)
array(1) {
["GET_LOCK("foobar", 2)"]=>
int(1)
}
(请注意GET_LOCK
结果为1)
第二个将返回(在第一个仍在运行时启动):
pid=(18393)
mysql connection id =(73)
array(1) {
["GET_LOCK("foobar", 2)"]=>
int(0)
}
(请注意GET_LOCK
结果为0 - 正如预期的那样,以及不同的pid和mysql连接ID)。
当从浏览器启动两次相同的脚本时 - 它报告两个脚本都成功获得了锁定。 首先回归:
pid=(11913) mysql connection id =(74) array(1) { ["GET_LOCK("foobar", 2)"]=> int(1) }
第二次返回(第一次仍在运行时):
pid=(11913) mysql connection id =(75) array(1) { ["GET_LOCK("foobar", 2)"]=> int(1) }
请注意,pids是相同的,但mysql连接ID不同,GET_LOCK
结果不符合预期,因为两者都返回1.
现在我很困惑。使用了不同的mysql连接(由CONNECTION_ID()返回),这表明不同的mysql会话。根据mysql文档,可以从 SAME 会话中获取更多具有相同名称的锁,但是在这里我有不同的mysql会话,对吧?
我甚至放了PDO::ATTR_PERSISTENT => false
,尽管这是默认值。
cmd行和浏览器的输出之间的唯一区别是pids(来自cmd行的两个已执行php脚本的不同pid,以及来自浏览器的两个已执行php脚本的相同pid)。
有什么想法发生了什么?就目前而言,对我来说,这似乎是一个主要问题,因为锁定悄然停止工作。 :(
感谢。