我正在尝试使用带有 PDO 的事务,代码如下
try
{
$bdd = new PDO('mysql:host=HOSTNAME;dbname=DATABASENAME', 'USERNAME', 'PASSWORD');
}
catch(Exception $e)
{
die('Error : '.$e->getMessage());
}
$qry = 'UPDATE table SET field = CASE';
foreach($elements as $el){
$qry .= ' WHEN id = '. $el['id'] .' THEN '. $el['value'];
}
$qry .= ' ELSE field END, SET update_date = CASE';
foreach($elements as $el){
$qry .= ' WHEN id = '. $el['id'] .' THEN NOW()';
}
$qry .= ' ELSE update_date END';
$update = $bdd->prepare($qry);
$bdd->beginTransaction();
try {
$update->execute();
$bdd->commit();
}
catch(Exception $e) {
$bdd->rollback();
echo 'Error : '.$e->getMessage().'<br />';
echo 'N° : '.$e->getCode();
exit();
}
但我收到以下错误(并且表格未更新):
Fatal error: Uncaught exception 'PDOException' with message 'There is no active transaction' in script.php:106
Stack trace:
#0 script.php(106): PDO->rollBack() #1 {main} thrown in script.php on line 106
(第 106 行是 $bdd->rollback();
)
我知道它告诉我没有交易正在进行,但是......应该有,$bdd->rollback();
......
感谢您提供的任何帮助!
编辑:数据库引擎是 MyISAM。
经过进一步测试,我有更多信息:
我简化了问题中的 $qry
,因为我认为它不相关,但似乎并非如此。我实际使用的查询要长得多,使用以下代码更新多个元素(我还修改了原始问题中的代码 ^):
$qry = 'UPDATE table SET field = CASE';
foreach($elements as $el){
$qry .= ' WHEN id = '. $el['id'] .' THEN '. $el['value'];
}
$qry .= ' ELSE field END, SET update_date = CASE';
foreach($elements as $el){
$qry .= ' WHEN id = '. $el['id'] .' THEN NOW()';
}
$qry .= ' ELSE update_date END';
似乎是查询的长度和/或更新的行数导致了我的问题:
- 最多更新72行时(查询长度为3463个字符,包括所有空格),更新表,
vardump($bdd->beginTransaction();)
返回bool(true)
(无论它是在$update = $bdd->prepare($qry)
行之前还是之后。 - 当更新 73 行或更多时(查询长度为 3509 个字符,包括所有空格,当它更新 73 行时),表不更新,并且
vardump($bdd->beginTransaction();)
返回bool(false)
(再一次,不管它是在$update = $bdd->prepare($qry)
行之前还是之后。
如能提供有关原因以及如何解决的提示,我们将不胜感激。
再次感谢
编辑 2:我将引擎切换为 InnoDB。问题仍然存在。
最佳答案
移动
$bdd->beginTransaction();
在您的查询上方:
$qry = 'UPDATE table SET field = value'
$update = $bdd->prepare($qry);
编辑:
您正在使用不支持事务的 MyISAM 引擎。更新您的表以使用 InnoDB。
关于php - 没有活跃的交易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33122212/