MySQL:PDO事务无法正常工作

时间:2017-12-20 15:06:14

标签: php mysql pdo transactions

所以我在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();
?>

我的第一次插入没有发痒。

第二个插入(在第一个事务中)确实被回滚。但是,我立即启动另一个事务,再次插入,然后再次回滚。通常情况下,我希望只收到&#34; 1&#34;在我的桌子里。

会发生什么事情会被回滚,但是在第三次插入之后,我再次回滚并收到以下错误消息:

致命错误:未捕获的异常&#39; PDOException&#39;有消息&#39;没有活动的交易&#39;在/home/.../.../.../testSQL.php:24堆栈跟踪:#0 /home/.../.../.../testSQL.php(24):PDO- &gt;第24行/home/.../.../.../testSQL.php中抛出的rollBack()#1 {main}

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

我绝对不明白发生了什么。为什么第一笔交易有效而不是第二笔?我的表格不包含&#34; 3&#34;。我不知道回滚是否仍然有效,尽管出现错误信息或者autocomit = 0阻止了值&#34; 3&#34;把它放到桌子上......我不知道。

有人有解释吗?

谢谢,

1 个答案:

答案 0 :(得分: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!