Transaktionen

Transaktionen garantieren, dass entweder alle Operationen innerhalb der Transaktion ausgeführt werden oder keine. Sie sind nützlich, um bei komplexen Operationen die Konsistenz der Daten sicherzustellen.

Am einfachsten sieht die Verwendung von Transaktionen so aus:

$database->beginTransaction();
try {
	$database->query('DELETE FROM articles WHERE id = ?', $id);
	$database->query('INSERT INTO audit_log', [
		'article_id' => $id,
		'action' => 'delete'
	]);
	$database->commit();
} catch (\Exception $e) {
	$database->rollBack();
	throw $e;
}

Dasselbe Ergebnis erreichen Sie viel eleganter mit der Methode transaction(). Sie nimmt einen Callback entgegen, der innerhalb der Transaktion ausgeführt wird. Läuft der Callback ohne Exception durch, wird die Transaktion automatisch committet. Tritt eine Exception auf, wird die Transaktion zurückgerollt und die Exception weiter nach oben gereicht.

$database->transaction(function ($database) use ($id) {
	$database->query('DELETE FROM articles WHERE id = ?', $id);
	$database->query('INSERT INTO audit_log', [
		'article_id' => $id,
		'action' => 'delete'
	]);
});

Aufrufe von transaction() lassen sich verschachteln, wodurch sich Methoden, die jeweils ihre eigene Transaktion verwalten, leicht zusammensetzen lassen. Nur die äußere Transaktion wird tatsächlich als BEGIN/COMMIT an die Datenbank geschickt; die inneren Aufrufe verfolgen lediglich die Verschachtelungstiefe. Ein manueller Aufruf von beginTransaction(), commit() oder rollBack() innerhalb eines transaction()-Callbacks wirft eine LogicException.

Die Methode transaction() kann auch Werte zurückgeben:

$count = $database->transaction(function ($database) {
	$result = $database->query('UPDATE users SET active = ?', true);
	return $result->getRowCount(); // gibt die Anzahl der aktualisierten Zeilen zurück
});