使用预准备语句后的PDO :: rollback

时间:2015-02-11 20:05:19

标签: pdo commit rollback

据我所知,为了防止注入攻击,PDO :: prepare首先将查询发送到服务器然后参数稍后进行;现在,我觉得这引入了另一个问题:这意味着PDO ::执行后无法回滚,或者我错过了什么?

我在应用程序中有两个表1和2。这两个表不应包含相同的行。当我使用INSERT INTO table1 SELECT FROM Table2时,如果INSERT查询成功,我想DELETE FROM table2。如果其中一个查询失败,我想回滚。所以我有以下代码:

$dbConn->beginTransaction();

$stmt1 = $dbConn->prepare( "INSERT INTO table1 ( field1, field2, field3  )   
        SELECT field1, field2, field3 FROM table2 WHERE field4 = :field4" );

$stmt1->execute( array( $field4 ) );

$stmt2 = $dbConn->prepare( "DELETE FROM table2 WHERE field4 = :field4" );

$stmt2->execute( array( $field4 ) );

if ( $stmt1->rowCount() > 0 && $stmt2->rowCount() > 0 )
{   
    $dbConn->commit();

    return true;
}
else
{
    $dbConn->rollBack();

    return false;
}

没有准备好的陈述,这很容易;但有了它,它看起来很难;以前有人做过这样的事吗?

感谢。

1 个答案:

答案 0 :(得分:-1)

这并不困难,从我能说的应该可以正常工作。但是我会重构代码以使用异常:

try {
  $dbConn->beginTransaction();

  $stmt1 = $dbConn->prepare( "INSERT INTO table1 ( field1, field2, field3  )   
        SELECT field1, field2, field3 FROM table2 WHERE field4 = :field4" );

  $stmt1->execute( array( $field4 ) );

  $stmt2 = $dbConn->prepare( "DELETE FROM table2 WHERE field4 = :field4" );

  $stmt2->execute( array( $field4 ) );


    if ( $stmt1->rowCount() > 0 && $stmt2->rowCount() > 0 )
    {   
      $dbConn->commit();
      return true;
    }
    else
    {
      throw new LogicException('Unequal row counts.');
    }
} catch (Exception $e) {
     $dbConn->rollBack();
      if ($e instanceof LogicException) {
         // just return
         return false;
      } else {
        // otherwise rethrow because something we didnt expect to go
        // wrong did
        throw $e;
      }
}

这样我们也会回滚,如果其他东西产生了PDO这样的异常,或者我们在数据准备过程中可能会做的其他事情。