我是受保护开发网站上的唯一用户。我有一个使用PHP每2秒刷新一次的卡表 - > MySQL查询。我已经使用计时器单独运行这些查询,它们都在0.01秒以内。我可以激活下面这样的功能,结果很快。但是,如果我将该功能垃圾邮件10次(从单击快速激活它的按钮),则会发生奇怪的事情。 mysqli将SELECT完全正常,甚至运行UPDATE查询,但UPDATE查询将影响0行而不是通常的1.没有任何错误出现在任何地方。大约2分钟后,功能将恢复正常,UPDATE现在将按预期生效1行,我只看到" 2"在屏幕上(用于回声调试测试)。
以下代码在问题出现时无处不在,没有错误。我只会看到" 234"在屏幕上显示SQL数据库与SELECT语句成功通信。 UPDATE语句似乎也经历了,但正如我所说,它们只影响0行而不是通常的1.在我停止垃圾邮件函数后等待2分钟后,UPDATE语句将正常影响行。
function sitDown($seat,$playername,$pass) {
global $conn;
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
#where $seat is INT of seat number (1-9)
$seatcheck="seat" . $seat . "_player";
$chipscheck="seat" . $seat . "_chips";
mysqli_autocommit($conn, FALSE);
$stmt=$conn->prepare("SELECT $seatcheck FROM tablebase FOR UPDATE");
#later $stmt->bind_param('sssd', $code, $language, $official, $percent);
$result = $stmt->execute() or trigger_error(mysqli_error($conn), E_USER_ERROR); #test error
$stmt->bind_result($seat_status);
$stmt->fetch();
$stmt->store_result();
echo 2;
if ($seat_status === "0") {
$stmt_bgn = $conn->prepare("SELECT username, deposit_current FROM userbase WHERE username=? AND pass =? AND deposit_current>0 AND seat=0 FOR UPDATE" );
$stmt_bgn->bind_param('ss', $playername, $pass);
$stmt_bgn->execute();
$result = $stmt_bgn->execute() or trigger_error(mysqli_error($conn), E_USER_ERROR); #test error
$stmt_bgn->bind_result($usern,$deposit_current);
$stmt_bgn->store_result();
$stmt_bgn->fetch();
$num_rows=$stmt_bgn->num_rows;
echo 3;
if ($num_rows == 1) {
$stmt3 = $conn->prepare("UPDATE tablebase SET $seatcheck=?, $chipscheck = ?");
if(!$stmt3) {die('prepare4 failed: ' . htmlspecialchars($conn->error));}
$stmt3->bind_param('si', $playername, $deposit_current);
$stmt3->execute();
$stmt3->store_result();
$stmt2 = $conn->prepare("UPDATE userbase SET deposit_current=deposit_current-deposit_current, seat=? WHERE username=? AND pass=?");
if(!$stmt2) {die('prepare4 failed: ' . htmlspecialchars($conn->error));}
#update above later for when deposit_current allows user to select their buy-in amount
$stmt2->bind_param('iss', $seat, $playername, $pass);
$stmt2->execute();
if(!$stmt2) {die('prepare4 failed: ' . htmlspecialchars($conn->error));}
$result = $stmt2->execute() or trigger_error(mysqli_error($conn), E_USER_ERROR);
$stmt2->store_result();
if(!$stmt2) {die('prepare4 failed: ' . htmlspecialchars($conn->error));}
mysqli_autocommit($conn, TRUE);
echo 4;
}
}
}
所有错误捕获只是暂时的而不是生产,我试图找出这个问题。不会在任何地方抛出或显示任何错误。我已启用完整的错误报告。
在我看来,MySQL服务器可能会出现延迟,但是如果是这种情况那么为什么" 234"显示在控制台中,表明SELECT语句正在通过?
当我检查错误日志时,没有任何内容。 slow_log什么都不显示,而general_log显示查询实际上已成功执行(包括UPDATES,虽然没有表生效,只是UPDATE查询成功执行,奇怪吗?)。使用和不使用SELECT FOR UPDATE时,无论是否使用事务都会出现此问题。
无论原因是什么,如果任何恶意用户只是垃圾邮件功能并阻塞整个网站,我就无法发布此程序。任何有关原因以及如何预防的想法都将受到赞赏。