2015-02-11 38 views
0

我知道为了防止注入攻击,PDO :: prepare首先将查询发送到服务器,然后参数稍后;现在,我觉得这引入了另一个问题:这意味着在PDO :: execute之后不能回滚,或者我错过了某些东西?使用准备好的语句后的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

为什么你认为准备会有所作为?事务处理表格数据。 – Barmar 2015-02-11 20:06:51

+0

有什么困难? – 2015-02-11 20:08:18

回答

-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或一些其他的事情,我们可以做作为我们的数据准备工作的一部分。