public function transaction(Closure $callback, $attempts = 1)
{
for ($a = 1; $a <= $attempts; $a++) {
$this->beginTransaction();
// We'll simply execute the given callback within a try / catch block
// and if we catch any exception we can rollback the transaction
// so that none of the changes are persisted to the database.
try {
$result = $callback($this);
$this->commit();
} catch (Exception $e) {
if ($this->causedByDeadlock($e) && $this->transactions > 1) {
--$this->transactions;
throw $e;
}
$this->rollBack();
if ($this->causedByDeadlock($e) && $a < $attempts) {
continue;
}
throw $e;
} catch (Throwable $e) {
$this->rollBack();
throw $e;
}
return $result;
}
}