2016-05-20 4 views
0

Ich bin ziemlich neu in Transaktionen.PHP, MySQL, PDO-Transaktionen - Ist der Code innerhalb versuchen Block Stop bei commit()?

Vor, was ich tat, war so etwas wie:

Codeblock 1

$db = new PDO(...); 

$stmt = $db->prepare(...); 

if($stmt->execute()){ 
    // success 
    return true; 
}else{ 
    // failed 
    return false; 
} 

Aber in einem Versuch, Gruppe mehrere Abfragen in einer einzigen Transaktion, ich bin jetzt mit so etwas wie :

Codeblock 2

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

$db->beginTransaction(); 

try{ 
    $stmt = $db->prepare(... 1 ...); 
    $stmt->execute(); 

    $stmt = $db->prepare(... 2 ...); 
    $stmt->execute(); 

    $stmt = $db->prepare(... 3 ...); 
    $stmt->execute(); 

    $db->commit(); 

    return true; 
}catch(Exception $e){ 
    // Failed, maybe write the error to a txt file or something 
    $db->rollBack(); 
    return false; 
} 

Meine Frage ist: Wenn die Transaktion aus irgendeinem Grund fehlschlägt, stoppt der Code bei $db->commit(); und springt zum catch Block? Oder würde der return true; zuerst laufen, und dann würde es versuchen, an die catch zu gehen? Denn wenn das der Fall ist, dann bin ich schon zurückgekehrt, und so würde es nicht zum catch gehen. UND es hätte den falschen Wert zurückgegeben.

Muss ich immer noch so etwas wie die folgenden:

Codeblock 3

if($stmt->commit()){ 
    return true; 
} 

oder genügt es, die Art, wie ich es in -Code Block 2 geschrieben haben?

+1

sein Ja, wenn der Code Stopp bei '$ db-> commit();' dann Ausgabe von 'catch' Block zurückgegeben werden, so dass Sie nicht brauchen, um eine Bedingung hinzuzufügen, wie' wenn ($ stmt-> commit()) .... 'http://php.net/manual/de/pdo.transactions.php – pes502

Antwort

1

Wenn die Transaktion aus irgendeinem Grund fehlschlägt, wird der Code an der sehr Linie stoppen, wo Fehler aufgetreten Ende dann die Ausführung springt direkt an den catch-Block . So ist es ausreichend, wie Sie es in Codeblock 2 geschrieben haben.

Beachten Sie, dass Sie immer die Ausnahme nach Rollback erneut werfen sollten. Sonst haben Sie nie eine Idee, was ein Problem war. So soll es

try{ 
    $stmt = $db->prepare(... 1 ...); 
    $stmt->execute(); 

    $stmt = $db->prepare(... 2 ...); 
    $stmt->execute(); 

    $stmt = $db->prepare(... 3 ...); 
    $stmt->execute(); 

    $db->commit(); 

    return true; 
}catch(Exception $e){ 
    $db->rollBack(); 
    throw $e; 
} 
+0

Was genau macht das "werfen"? Kann ich nicht einfach über '$ e-> getMessage()' auf die Ausnahme zugreifen? – Birrel

+0

Sie können, aber Sie sollten nicht. Ausnahmen sollen nicht gleich behandelt werden. Es ist Programmieren. Sie sollten den Bearbeitungscode nur einmal schreiben, nicht jedes Mal, wenn Sie eine Abfrage ausführen. Außerdem, was, wenn Sie eines Tages Ihre Meinung ändern und eine andere Idee haben, den Fehler als die Protokollierung zu verarbeiten? Wird sich das Massenumschreiben einstellen? –

+0

Abgesehen von diesem speziellen Fall kann PHP Fehler bereits für Sie protokollieren. Bedeutet, wenn Sie loggen müssen, müssen Sie nicht eine einzige Zeile schreiben, speichern für 'ini_set ('log_errors', 1);' one –

0

, wenn Sie einen Fehler stehen Sie können dies tun, alle Transaktionen wie diese

catch(Exception $e){ 
    $db->rollBack(); 
    // Failed, maybe write the error to a txt file or something 
    return false; 
} 
+0

Amit, danke. Ich habe vergessen, diese Zeile in die Frage zu stellen, aber es ist in meinem Code. Aber deine Antwort geht nicht auf meine Frage ein. Der Rollback betrifft mich nicht, sondern irgendeinen Code, der über die '$ stmt-> commit(); -Zeile hinaus existiert. – Birrel

+0

Wenn einer Ihrer Transaktionscodes fehlschlägt, wird er in Ihren catch-Block geschrieben. Welcher Code auch immer im catch-Block ist, wird ausgeführt. –

1

Die Ausführung gestoppt wird, rückgängig zu machen, wenn eine Ausnahme ausgelöst wird.

Die erste Rückgabe wird nicht erreicht, aber die catch-Anweisung wird ausgeführt.

Sie können sogar direkt begehen zurück:

$dbh->beginTransaction(); 
try { 
    // insert/update query 
    return $dbh->commit(); 
} catch (PDOException $e) { 
    $dbh->rollBack(); 
    return false; 
}