【问题标题】:MySQL: PDO transactions not working properlyMySQL:PDO 事务无法正常工作
【发布时间】:2018-06-03 04:30:36
【问题描述】:

所以我在使用 PDO 中的事务时遇到了问题。我正在做一个快速测试:

<?php
include_once "./init.php";

$sql = "insert into tbTest(cValue) values('1');";
$sttmt = $db->prepare($sql);
$sttmt->execute(); 

$sql = "SET autocommit=0;";
$sttmt = $db->prepare($sql);
$sttmt->execute();  

$db->beginTransaction();
$sql = "SET autocommit=0; insert into tbTest(cValue) values('2');";
$sttmt = $db->prepare($sql);
$sttmt->execute();  
$db->rollBack();

$db->beginTransaction();
$sql = "SET autocommit=0; insert into tbTest(cValue) values('3');";
$sttmt = $db->prepare($sql);
$sttmt->execute();  
$db->rollBack();
?>

我的第一次插入没有痒就通过了。

第二次插入(在第一个事务中)确实会回滚。但是,我之后立即开始另一个事务,再次插入,然后再次回滚。通常,我希望在我的表中只收到“1”。

发生的情况是 2 被回滚,但在第三次插入后,我再次回滚并收到以下错误消息:

致命错误:在 /home/.../.../.../testSQL.php:24 堆栈跟踪:#0 /home/ 中未捕获异常“PDOException”并显示消息“没有活动事务”。 ../.../.../testSQL.php(24): PDO->rollBack() #1 {main} 在 /home/.../.../.../testSQL.php 上抛出第 24 行

现在请忽略 # 行,我没有包含 html 内容。第 24 行是第二个 rollBack()。插入值“3”之后的那个。

我完全不明白发生了什么。为什么第一笔交易有效而第二笔交易无效?我的表不包含“3”。尽管有错误消息,我不知道回滚是否有效,或者 autocomit=0 是否阻止了值“3”进入表...我不知道。

有人解释一下吗?

谢谢,

【问题讨论】:

  • 尝试从您的 INSERT 语句中删除 SET autocommit=0;,这应该被 beginTransaction() 覆盖
  • 天啊...是的,你是对的。当我第一次研究这个时,我已经设置了自动提交。我的表是 MyISAM 表,我不知道它不能参与事务。我已经把 set autocommit 放回去了。然后我在写这个问题之前将它切换到 InnoDB,但离开了 autcommit。进行了一些调试以使其正常工作,但现在可以了。非常感谢!

标签: php mysql pdo transactions


【解决方案1】:

正如 Nigel Ren 所指出的,问题在于设置的自动提交。 MyISAM 表不能管理事务。当我的表是 MyISAM 时,我已经添加了 set autocommit 作为我的测试的一部分,而当我切换到 InnoDB 时忘记删除它。

有效的版本:

<?php
//not in a transaction
$sql = "insert into tbTest(cValue) values('1');";
$sttmt = $db->prepare($sql);
$sttmt->execute(); 

$db->beginTransaction();
$sql = "insert into tbTest(cValue) values('2');";
$sttmt = $db->prepare($sql);
$sttmt->execute();  
$db->rollBack();

$db->beginTransaction();
$sql = "insert into tbTest(cValue) values('3');";
$sttmt = $db->prepare($sql);
$sttmt->execute();  
$db->commit();

//not in a transaction
$sql = "insert into tbTest(cValue) values('4');";
$sttmt = $db->prepare($sql);
$sttmt->execute();  


$db->beginTransaction();
$sql = "insert into tbTest(cValue) values('5');";
$sttmt = $db->prepare($sql);
$sttmt->execute();  
$db->rollBack();


//not in a transaction
$sql = "insert into tbTest(cValue) values('6');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
?>

只有值 1、3、4 和 6 才能进入表格。这是预期的结果!

再次感谢 Nigel Ren!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多