2015-02-11 115 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或一些其他的事情,我們可以做作爲我們的數據準備工作的一部分。