【发布时间】:2019-03-13 12:28:11
【问题描述】:
是否可以在MySQL TRANSACTION 之外运行MySQL INSERT 命令?
我需要这个,因为我正在记录数据库中的所有错误,即使其他 MySQL 查询在发生错误时应回滚,错误仍应插入到数据库中。
这是一个代码示例:
<?php
DB('main')->query("START TRANSACTION;");
$error = false;
for ($i=0; $i<10; $i++) {
$rand = rand(0, 10);
if ($rand < 5) {
$error = true;
DB('main')->query("INSERT INTO Errors SET ErrorText = 'There was an error'");
break;
}
DB('main')->query("INSERT INTO RandomTable SET RandomValue = '" . $rand . "'");
}
if ($error) {
DB('main')->query("ROLLBACK");
} else {
DB('main')->query("COMMIT");
}
使用此代码,如果发生错误,Errors 表中的行将根本不会插入。如果我不使用TRANSACTIONS,我必须手动删除在错误发生之前插入的所有行。
我知道,我可以简单地将错误的 INSERT 放在 ROLLBACK 命令之后,但是想象一下,有 50 个可能发生错误的地方,每个错误都不同。
【问题讨论】:
-
简短回答,当然可以。没有什么会迫使您首先使用事务。如果您可以提供一些代码或其他上下文,您的问题可能会更清楚。
-
@Dave 添加了一个代码示例。
-
最简单的方法大概是将错误日志存储在不受事务影响的MyISAM表中。
-
@DagSondreHansen 我不知道这一点,但我会测试它,如果它真的这样工作,那将完全满足我的需求!
-
关于在事务中使用 MyISAM 表的建议:不建议这样做,可能会导致复制期间出现奇怪的行为。对于标准 MySQL 复制,这将导致 MyISAM 条目最终出现在二进制日志中在 InnoDB 事务之前。对于 Galera 复制,当在混合事务期间发生回滚时,这甚至会破坏整个集群。