2016-12-30 76 views
2

我遇到了PHP脚本中的事务问题。如果至少其中一个失败,我想进行多次查询并能够全部回忆它们。下面你可以找到脚本的一个简单的例子,我使用的:如果我删除线PHP PDO - 没有活动交易

Uncaught exception 'PDOException' with message 'There is no active transaction'

$tags_input = array(6,4,5); 
$conn = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8', 
DB_USER, DB_PASSW, array( 
    PDO::ATTR_EMULATE_PREPARES => false, 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'")); 

    $conn->beginTransaction(); 

    $sql = "INSERT INTO projects (id, pr_id, enabled) VALUES (:val0, :val1, :val2)"; 
    $stmt = $conn->prepare($sql); 
    if(count($tags_input)>0){ 
      for($i = 0;$i<count($tags_input);$i++){ 
        $stmt->bindValue(':val0', 57); 
        $stmt->bindValue(':val1', $tags_input[$i]); 
        $stmt->bindValue(':val2', 'Y'); 
        $result = $stmt->execute(); 

      } 

    } 

    $res1 = $conn->commit(); 
    $conn->rollBack(); 

现在,这个例子产生一个错误 $ conn->回滚() ; 错误消失,因此我不明白为什么pdo对象无法看到打开的事务(开始交易和提交不会产生任何错误)。我也尝试把rollBack()放入事务中,但没有任何区别。我仍然收到错误'没有活动的交易。

我在InnoDB上运行PHP 5.6和Mysql表。

+2

您在这里commiting交易:'$ RES1 = $ conn->提交();'所以你不能回滚 – e4c5

+0

尝试包装你的交易代码为try-catch语句,如在第一例http://php.net/manual/en/pdo.transactions.php –

+0

https://phpdelusions.net/pdo#transactions –

回答

2

将您的事务代码包装在try-catch语句中。

//try { 
$tags_input = array(6,4,5); 
$conn = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8', 
DB_USER, DB_PASSW, array( 
    PDO::ATTR_EMULATE_PREPARES => false, 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'")); 
} catch (Exception $e) { 
    die("Unable to connect: " . $e->getMessage()); 
}  
try { 
    $conn->beginTransaction(); 
    $sql = "INSERT INTO projects (id, pr_id, enabled) VALUES (:val0, :val1, :val2)"; 
    $stmt = $conn->prepare($sql); 
    if(count($tags_input)>0){ 
      for($i = 0;$i<count($tags_input);$i++){ 
        $stmt->bindValue(':val0', 57); 
        $stmt->bindValue(':val1', $tags_input[$i]); 
        $stmt->bindValue(':val2', 'Y'); 
        $result = $stmt->execute(); 
      } 
    } 
$res1 = $conn->commit();  
} catch (Exception $e) { 
    $conn->rollBack(); 
    echo "Failed: " . $e->getMessage(); 
} 

编辑

一个真正良好的基础,答案简单明了的解释是由Richard为注释提供。

The reason you got error is because you were trying to close a transaction when it was already closed. beginTransaction opens one, and EITHER rollBack OR commit closes it. You have to avoid doing BOTH actions, meaning commit/rollback, for a single beginTransaction statement, or you'll get an error. The above try/catch code ensures that only one closing statement is executed.

+0

嗨,感谢您快速回答。它似乎工作!但是,我不知道为什么。如果没有try/catch块,不可能使用转换吗?另外,我认为这里的回滚是无关紧要的,因为我试图将它从代码中拿出来,也没有在数据库中得到任何新记录(这是想法,但不知道为什么会发生) – user1857756

+0

它是相同的理由为@ e4c5在评论中写道。我很高兴它解决了你的问题圣诞快乐:) –

+1

只是为了增加这一点,你得到错误的原因是因为你试图关闭一个事务时,它已经关闭。 “beginTransaction”打开一个,然后“rollback”或“commit”关闭它。 您必须避免为单个“beginTransaction”语句执行提交/回滚操作,否则会出现错误。 上面的try/catch代码确保只执行1个“关闭”语句。 –