【发布时间】: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->rollback();)
我知道它告诉我没有交易正在进行,但是...应该有,$bdd->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->beginTransaction();)返回bool(true)(不管是在$update = $bdd->prepare($qry)行之前还是之后。 - 当更新 73 行或更多时(查询长度为 3509 个字符,包括所有空格,当它更新 73 行时),表没有更新,
vardump($bdd->beginTransaction();)返回bool(false)(再次,不管它是否位于$update = $bdd->prepare($qry)行之前或之后。
感谢您提供有关原因以及如何解决此问题的提示。
再次感谢
EDIT 2:我将引擎切换到 InnoDB。问题依然存在。
【问题讨论】:
-
返回
bool(false) -
确保 PDO 将在错误时抛出异常:
$bdd->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->beginTransaction() #1 {main} thrown in script.php on line 75,第 75 行是$bdd->beginTransaction();。我不知道这意味着什么...... -
您是否会将生成的 SQL 保存到文件中,然后尝试在
SQL Manager中运行相同的查询,例如phpmyadmin?我想知道这是 PDO 问题还是服务器问题。 B.5.2.9 MySQL server has gone away。一种可能性是“查询太大”。 ;-/ 但它必须非常大。因此将其存储在一个文件中,以便您检查它。您发送的要更新的数据的大小是多少? -
我不知道为什么会有效果。我很难理解您所看到的效果。我看不出我如何能提供进一步的帮助。对不起。
标签: php mysql pdo transactions