2017-03-14 6 views
2

Kann ich während der DB-Transaktion einige Checkpoints erstellen?Laravel DB-Transaktionen mit mehreren Commits?

Zum Beispiel, wenn die Transaktion startet, habe ich viele Abfragen, Updates, Löschungen und so weiter.

DB::transaction(function() { 
    DB::table('users')->update(['votes' => 1]); 
    // something else here 
    DB::table('posts')->delete(); 
}); 

Soweit ich verstehe, würde diese Art der Funktion automatisch alles im Erfolgsfall Commit und Rollback, wenn etwas schief geht.

Aber wäre es möglich, nicht alles im Fehlerfall rückgängig zu machen, zum Beispiel, wie

DB::table('users')->update(['votes' => 1]); 
// something else here 
DB::if_successful_so_far_do_not_rollback_previous_lines(); 
DB::table('posts')->delete(); 

alle „kleinen inneren Commits“ gibt es?

+2

Warum teilen Sie es dann nicht in zwei Commits auf? :) – manniL

+0

Ich versuche, so wenig Verbindungen wie möglich zu verwenden – Coffee

+0

Nun, ich denke, das wäre die einzige Lösung. Ich glaube nicht, dass Sie eine Transaktion nur "teilweise zurücknehmen" können. – manniL

Antwort

2

Ja, Sie können. Dies hängt jedoch auch von der verwendeten Datenbank ab.

Laravel unterstützt verschachtelte Transaktionen. Was ist etwas, was nahe ist, was Sie brauchen.

Um eine innere Transaktion zu isolieren, müssen Sie sie in einen try-catch-Block einfügen. Wenn also die innere Transaktion eine Ausnahme auslöst, wird sie die äußere Transaktion nicht erreichen und daher den Prozess fortsetzen. Wenn die äußere Transaktion jedoch eine Ausnahme auslöst, wird die gesamte Transaktion (einschließlich ihrer verschachtelten Transaktionen) zurückgesetzt.

So werden Sie mit etwas am Ende wie folgt:

public function testNestedTransactions() 
{ 

    $user = EloquentTestUser::create(['email' => '[email protected]']); 

    $this->connection()->transaction(function() use ($user) { 

     try { 
      $this->connection()->transaction(function() use ($user) { 
       $user->email = '[email protected]'; 
       $user->save(); 
       throw new Exception; 
      }); 
     } catch (Exception $e) {} 

     $user = EloquentTestUser::first(); 
     $this->assertEquals('[email protected]', $user->email); 

    }); 

} 

Dies ist ein Test von Otwell in this commit implementing the functionality of nested transactions in Laravel geschrieben. Er erstellt zuerst einen Benutzer und startet dann eine Transaktion mit einer verschachtelten Transaktion, in der er die Benutzer-E-Mail aktualisiert und dann eine Ausnahme auslöst (was bedeutet, dass ein Fehler aufgetreten ist). Direkt darunter überprüft er, ob die E-Mail-Adresse des Benutzers bei der Erstellung unverändert bleibt, und zwar, weil die verschachtelte Transaktion zurückgesetzt wurde, die äußere Transaktion jedoch noch läuft.

Verwandte Themen