【问题标题】:Transaction committed despite of error尽管有错误但仍提交交易
【发布时间】:2015-12-26 19:14:32
【问题描述】:

我对 PDO 和提交多查询有疑问。 这是我的php代码:

public function executeSql($multiQuery, $conn)
{
    $arrQuery = mb_split(';\s*?(-- )?.*?\n', $multiQuery);

    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $conn->beginTransaction();
    try {
        foreach ($arrQuery as $query) {
            if (strlen(trim($query)) > 0) {
                echo "<BR><BR>" . $query;
                $conn->exec($query);
            }
        }
    } catch (Exception $e) {
        echo "<hr>RollBack";
        $conn->rollback();
        throw $e;
    }
    echo "<hr>Commit";
    $conn->commit();
    return true;
}

还有我的 SQL:

INSERT INTO config_new SET nazwa='test', wartosc=123;

ALTER TABLE `koszty_rodzaje` DROP FOREIGN KEY `koszty_rodzaje_ibfk_2`,
ADD FOREIGN KEY (`temat_id`) REFERENCES `tematy` (`temat_id`)
ON DELETE CASCADE
ON UPDATE CASCADE;

第二个查询产生错误,但第一个总是插入:/

这是我的回复:

INSERT INTO config_new
SET nazwa = 'dummy', wartosc = 1;

ALTER TABLE `koszty_rodzaje` DROP FOREIGN KEY `koszty_rodzaje_ibfk_2`,
ADD FOREIGN KEY (`temat_id`) REFERENCES `tematy` (
`temat_id`
)
ON DELETE CASCADE
ON UPDATE CASCADE;


INSERT INTO config_new SET nazwa='test', wartosc=123

ALTER TABLE `koszty_rodzaje` DROP FOREIGN KEY `koszty_rodzaje_ibfk_2`, ADD FOREIGN KEY (`temat_id`) REFERENCES `tematy` (`temat_id`) ON DELETE CASCADE ON UPDATE CASCADE;
RollBack
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: 
General error: 1025 Error on rename of 
'./smaczny39/koszty_rodzaje' to './smaczny39/#sql2-3212-dafd68' 
(errno: 152)' in /glowna/funkcje/klient.class.php:502 

Stack trace: #0 /glowna/funkcje/klient.class.php(502): 
  PDO->exec('???ALTER TABLE ...') #1 /glowna/funkcje/klient.class.php(550): 
  cl_klient->executeSql('INSERT INTO con...', Object(PDO)) 
  #2 /glowna/admin.php(41): 
   cl_klient->cron_aktualizuj_baze_klienta('1111', '2.0.0-pre.1') 
  #3 {main} thrown in /glowna/funkcje/klient.class.php on line 502

如您所见,RollBack 已执行,但没有 Commit,那么为什么要在 DB 中插入第一个查询?

如果我这样查询:

INSERT INTO config_new SET nazwa='test', wartosc=123;

INSERT INTO config_new SET nazwa=testa, wartosc=123;

也出现错误,没有插入新值,因此可以正常工作。

【问题讨论】:

  • DDL 语句通常会导致隐式提交。

标签: php mysql pdo transactions


【解决方案1】:

MySQL 总是在 ALTER TABLE 开始之前提交事务。因此,如果 INSERT 查询有效,则无论 ALTER TABLE 是否有效,它都会执行。

更多信息在这里:https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

【讨论】:

  • 我可以测试和测试:/ 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
  • 2018-12-06
  • 2021-09-09
相关资源
最近更新 更多