Transazioni

Le transazioni garantiscono che vengano eseguite o tutte le operazioni della transazione, oppure nessuna. Sono utili per mantenere la coerenza dei dati durante operazioni complesse.

Il modo più semplice di usare le transazioni è questo:

$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;
}

Lo stesso risultato lo ottenete in modo molto più elegante con il metodo transaction(). Accetta un callback che viene eseguito all'interno della transazione. Se il callback termina senza eccezioni, la transazione viene confermata automaticamente. Se si verifica un'eccezione, la transazione viene annullata e l'eccezione viene propagata oltre.

$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'
	]);
});

Le chiamate a transaction() si possono annidare, il che rende facile comporre metodi che gestiscono ciascuno la propria transazione. Al database viene effettivamente inviata come BEGIN/COMMIT solo la transazione più esterna; le chiamate interne si limitano a tenere traccia della profondità di annidamento. Chiamare a mano beginTransaction(), commit() o rollBack() dentro il callback di transaction() provoca una LogicException.

Il metodo transaction() può anche restituire valori:

$count = $database->transaction(function ($database) {
	$result = $database->query('UPDATE users SET active = ?', true);
	return $result->getRowCount(); // restituisce il numero di righe modificate
});
versione: 4.x