更新查询有时不更新mySQL数据库中的字段

更新查询有时不更新mySQL数据库中的字段,mysql,innodb,Mysql,Innodb,我有一个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_a

我有一个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";
当失败时,结果、同步日期和更新时间将更新,但状态保持不变

还有一个查询只更新state字段,并且该查询也会间歇性失败

我无法在我们的测试环境中重现该问题。生产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
创建状态为0的行。
并且该行更新为state=1
cron作业提取all state=1并发送api调用
如果api调用成功,该行将更新为state=2、result、date\u synced和updated\u at
如果api调用出错,则该行将更新为state=3、result和updated_
状态字段永远不会设置回0(闪存后)或1(api调用后)。由于正在设置日期_synced和结果,但(有时)状态仍然为1,这就好像删除了对状态字段的更新

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

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

此外,它是否可重复;你能在完全相同的数据上运行相同的查询,它会做不同的事情吗

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

您是否尝试过对表进行修复和优化?这可能会有帮助

很抱歉回答:p

将MySQL中的“严格”重新调整为传统:

SET sql_mode = 'TRADITIONAL';
并尝试在不使用PHP的情况下从控制台插入。然后检查可以解释它的错误

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

或者,如果您使用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未设置为在脚本中显示错误。

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

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

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

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

下一步:在PHP的exec()之后设置“state”=2(进程中)。在这种情况下,如果后台的bash脚本比PHP运行MySQL更新查询更快地完成任务,那么您将得到更新的日期值,并且“state”=2(但一秒钟前它的值为3)


我遇到了这个问题。

您应该添加一个更新触发器和一个日志表,用于存储新旧值以及id、会话id和当前用户,以便进行调试。也许这些变化过去了,但被另一种说法覆盖了。我认为鲁福爵士的评论可能对你的情况非常有帮助,因为它将有助于确定事情发生的顺序,以及是否是一种更复杂的情况,在这种情况下,多个查询会导致你看到的图片由于同一行中的其他字段已更新,因此没有锁定问题。innodb可以锁定的最小的东西是一行。我无法锁定单个字段。在更新大量行时,我也看到了我们的数据库存在此问题。你找到了罪魁祸首/修复程序了吗?实际上,很可能MySQL正在生成警告,因为INT(1)已被截断或其他原因。因此PHP可能会忽略警告并继续。FWIW、INT(1)和INT(1000000)对于存储和支持的值范围来说完全相同。参数不是长度限制,而是显示提示。MySQL的INT始终是32位数据类型。
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;
}