【问题标题】:No active transaction没有活跃的交易
【发布时间】:2016-01-12 08:34:49
【问题描述】:

我正在尝试使用带有 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-&gt;rollback();

我知道它告诉我没有交易正在进行,但是...应该有,$bdd-&gt;rollback();...

感谢您提供的任何帮助!


EDIT:数据库引擎是 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-&gt;beginTransaction();) 返回bool(true)(不管是在$update = $bdd-&gt;prepare($qry) 行之前还是之后。
  • 当更新 73 行或更多时(查询长度为 3509 个字符,包括所有空格,当它更新 73 行时),表没有更新,vardump($bdd-&gt;beginTransaction();) 返回bool(false)(再次,不管它是否位于$update = $bdd-&gt;prepare($qry) 行之前或之后。

感谢您提供有关原因以及如何解决此问题的提示。

再次感谢


EDIT 2:我将引擎切换到 InnoDB。问题依然存在。

【问题讨论】:

  • 返回bool(false)
  • 确保 PDO 将在错误时抛出异常:$bdd-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);。我怀疑不是查询的大小而是内容的大小。
  • 我现在收到一个新错误:Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' in script.php:75 Stack trace: #0 script.php(75): PDO-&gt;beginTransaction() #1 {main} thrown in script.php on line 75 ,第 75 行是 $bdd-&gt;beginTransaction();。我不知道这意味着什么......
  • 您是否会将生成的 SQL 保存到文件中,然后尝试在 SQL Manager 中运行相同的查询,例如 phpmyadmin?我想知道这是 PDO 问题还是服务器问题。 B.5.2.9 MySQL server has gone away。一种可能性是“查询太大”。 ;-/ 但它必须非常大。因此将其存储在一个文件中,以便您检查它。您发送的要更新的数据的大小是多少?
  • 我不知道为什么会有效果。我很难理解您所看到的效果。我看不出我如何能提供进一步的帮助。对不起。

标签: php mysql pdo transactions


【解决方案1】:

移动

$bdd->beginTransaction();

到您的查询上方:

$qry = 'UPDATE table SET field = value'
$update = $bdd->prepare($qry);

编辑:

您正在使用不支持事务的 MyISAM 引擎。更新您的表以使用 InnoDB。

【讨论】:

  • 您能否更新您的帖子以显示您的 PDO 连接代码?
  • 我不确定我是否添加了您的要求,但它已更新
  • 代码对我有用,您使用的是什么数据库引擎?您应该使用支持事务的 InnoDB。
  • 感谢此见解。数据库引擎是 MyISAM,但我认为这不是问题:我发现var_dump($bdd-&gt;beginTransaction()); 返回true 的情况。似乎问题可能与查询的长度有关。我编辑了原始问题以添加我发现的内容,请您再看一下吗?
  • 更改为 InnoDB。 MyISAM 不支持事务。查询没问题。你所有的代码都在我的 InnoDB 表测试中工作,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多