wake-up-neo.net

Laravel: Verwenden von try ... catch mit DB :: transaction ()

Wir alle verwenden DB::transaction() für mehrere Einfügeabfragen. Sollte dabei ein try...catch Hineingelegt oder eingepackt werden? Muss überhaupt ein try...catch Angegeben werden, wenn eine Transaktion automatisch fehlschlägt, wenn etwas schief geht?

Beispiel try...catch, Das eine Transaktion umschließt:

// try...catch
try {
    // Transaction
    $exception = DB::transaction(function() {

        // Do your SQL here

    });

    if(is_null($exception)) {
        return true;
    } else {
        throw new Exception;
    }

}
catch(Exception $e) {
    return false;
}

Das Gegenteil, eine DB::transaction(), die einen Versuch einschließt ... catch:

// Transaction
$exception = DB::transaction(function() {
    // try...catch
    try {

        // Do your SQL here

    }
    catch(Exception $e) {
        return $e;
    }

});

return is_null($exception) ? true : false;

Oder einfach eine Transaktion ohne einen Versuch ... fangen

// Transaction only
$exception = DB::transaction(function() {

    // Do your SQL here

});

return is_null($exception) ? true : false;
57
enchance

Für den Fall, dass Sie eine Transaktion manuell durch Code beenden müssen (sei es durch eine Ausnahme oder einfach durch Überprüfen eines Fehlerzustands), sollten Sie nicht DB::transaction() verwenden, sondern stattdessen Ihren Code in DB::beginTransaction und DB::commit/DB::rollback():

DB::beginTransaction();

try {
    DB::insert(...);
    DB::insert(...);
    DB::insert(...);

    DB::commit();
    // all good
} catch (\Exception $e) {
    DB::rollback();
    // something went wrong
}

Siehe Transaktionsdokumente .

132
alexrussell

Wenn Sie PHP7 verwenden, verwenden Sie Throwable in catch, um Benutzerausnahmen und schwerwiegende Fehler abzufangen.

Beispielsweise:

DB::beginTransaction();

try {
    DB::insert(...);    
    DB::commit();
} catch (\Throwable $e) {
    DB::rollback();
    throw $e;
}

Wenn Ihr Code mit PHP5 kompatibel sein muss, verwenden Sie Exception und Throwable:

DB::beginTransaction();

try {
    DB::insert(...);    
    DB::commit();
} catch (\Exception $e) {
    DB::rollback();
    throw $e;
} catch (\Throwable $e) {
    DB::rollback();
    throw $e;
}
17
mnv

Sie könnten die Transaktion über try..catch wickeln oder sogar rückgängig machen, hier mein Beispielcode, den ich in laravel 5 , verwendet habe, wenn Sie tief in DB:transaction() in Illuminate\Database\Connection schauen dass das gleiche wie Sie manuelle Transaktion schreiben,

Laravel-Transaktion

public function transaction(Closure $callback)
    {
        $this->beginTransaction();

        try {
            $result = $callback($this);

            $this->commit();
        }

        catch (Exception $e) {
            $this->rollBack();

            throw $e;
        } catch (Throwable $e) {
            $this->rollBack();

            throw $e;
        }

        return $result;
    }

sie können also Ihren Code wie folgt schreiben und Ihre Ausnahmebedingung so behandeln, als würden Sie eine Nachricht per Flash zurück in Ihr Formular werfen oder auf eine andere Seite umleiten. REMEMBER return inside closure wird in transaction () zurückgegeben. Wenn Sie also redirect()->back() zurückgeben, wird es nicht sofort umgeleitet, da es bei einer Variablen zurückgegeben wird, die die Transaktion abwickelt.

Wrap-Transaktion

$result = DB::transaction(function () use ($request, $message) {
   try{

      // execute query 1
      // execute query 2
      // ..

      return redirect(route('account.article'));

   } catch (\Exception $e) {
       return redirect()->back()
          ->withErrors(['error' => $e->getMessage());
    }
 });

// redirect the page
return $result;

dann ist die Alternative, eine boolesche Variable zu werfen und die Weiterleitung außerhalb der Transaktionsfunktion zu handhaben. Wenn Sie abrufen möchten, warum die Transaktion fehlgeschlagen ist, können Sie sie von $e->getMessage() inside catch(Exception $e){...} abrufen.

8