9

我有一个 mySQL 更新查询,有时会更新所有字段,有时会更新除一个以外的所有字段。

它在大约 10% 的调用中失败。

我的桌子是:

CREATE TABLE IF NOT EXISTS `grades` (   
`id` int(11) NOT NULL AUTO_INCREMENT,   
`state` int(1) NOT NULL,   
`result` varchar(255) NOT NULL,   
`date_synced` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`) ) 
ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4395 ;

我的查询是:

$sqlstr = "UPDATE grades SET result = '$result', state = 2, date_synced = '$date', updated_at = '$date' WHERE id = $id";

当失败时,result、date_synced 和 updated_at 会更新,但状态保持不变。

还有另一个查询只更新状态字段,并且也间歇性地失败。

我一直无法在我们的测试环境中重现问题。生产 mySQL 数据库是否有问题或某种锁定冲突?


我有更多信息。我正在使用 mysqli。另一个只更新状态的查询是使用 mysql。这会导致问题吗?

我以为 InnoDB 按行锁定。它不允许部分行更新,是吗?


另一个更新来解决评论。

我的代码流非常线性。

The row is created with state=0.
<flash stuff here> and the row is updated with state=1
A cron job pulls all state=1 and sends an api call
if api call is successful, the row is updated with state=2, result, date_synced, and updated_at
if api call is error, the row is updated with state=3, result, and updated_at

state 字段永远不会设置回 0(在 flash 之后)或 1(在 api 调用之后)。由于 date _synced 和 result 正在设置,但(有时)状态仍为 1,这就像对 state 字段的更新正在被删除。

我将添加更新触发器,看看是否能提供更多信息。

4

4 回答 4

1

它是否说明“{n} 行受影响?”

此外,它是否可重复?你可以对完全相同的数据运行相同的查询,它会做不同的事情吗?

如果是这样,您可能有损坏的安装或损坏的数据库。

您是否尝试过对桌子进行修复和优化?那会有所帮助。

很抱歉的回答很抱歉:P

于 2013-01-08T23:21:15.937 回答
0

尝试将字段名称从“state”更改为其他名称,例如“state_num”。虽然它没有被列为 MySQL 的保留字,但它的名称可能会导致问题。

于 2013-02-15T23:50:08.137 回答
0

将 MySQL 中的“严格性”重新调整为 TRADITIONAL:

SET sql_mode = 'TRADITIONAL';

并尝试在没有 PHP 的情况下从控制台插入。然后检查可以解释它的错误。

通过以下方式将严格性重置为“宽容”:

SET sql_mode = '';

或者,如果您使用 PDO 对象连接到数据库,则通过 PHP 得到一个错误,如下所示:

try {
  $sqlstr = "UPDATE grades SET result = '$result', state = 2, date_synced = '$date',updated_at = '$date' WHERE id = $id";
$s = $pdo->exec($sqlstr);
}
catch (PDOException $e) {
  $error = $e->getMessage();
  echo $error;
}

基本上,尽一切可能获取正在发生的错误消息。很可能 SQL 正在发送错误,但 PHP 未设置为在您的脚本中显示它。

于 2013-02-13T01:17:45.953 回答
0

您设置“状态”和其他字段的查询会运行两次,有时您的一项任务比另一项完成得更快。它会更新所有字段,并且调用该任务的脚本还会运行更新“状态”字段的 MySQL 查询。

例如,您有一个 PHP 脚本,它通过 exec() 在后台运行 shell 命令“tar”,并在完成后在 DB 中设置“状态”。您的 PHP 代码的下一个字符串会更新您数据库中的“状态”。但有时,您调用的 bash 命令的运行速度比 PHP 脚本调用 MySQL 更新的速度快(如果此 bash 命令在后台模式下运行)。

第一步:从 PHP 运行 bash 脚本,在完成后设置“state”=3(等待进一步处理),用日期等更新其他字段。

下一步:在 exec() 之后的 PHP 中设置“state” = 2(正在进行中)。在这种情况下,如果您在后台的 bash 脚本比 PHP 运行 MySQL 更新查询更快地完成这项工作,您将获得更新的日期值以及“状态”= 2(但它在一秒钟前的值 = 3)。

我有这个问题。

于 2017-10-26T23:05:04.827 回答