rollbackAfter<T> method
Runs body in a transaction that is always rolled back (Laravel
RefreshDatabase). Application transactions inside become savepoints
and their after-commit callbacks fire when they "commit", as they
would without the wrapper.
Implementation
Future<T> rollbackAfter<T>(
Future<T> Function() body, {
String? connection,
}) async {
if (_activeScope(connection) != null) {
throw StateError('rollbackAfter cannot be nested inside a transaction.');
}
final connectionName = connection ?? config.defaultConnection;
final driver = await this.connection(connection);
final baseline = <FutureOr<void> Function()>[];
late T result;
try {
await driver.transaction<void>((tx) {
final scope = _TransactionScope(tx, this, connectionName);
return runZoned<Future<void>>(
() async {
result = await body();
throw const _RollbackSignal();
},
zoneValues: <Object?, Object?>{
transactionKey: scope.executor,
_scopeKey: scope,
depthKey: 1,
afterCommitKey: baseline,
baselineKey: baseline,
},
).whenComplete(scope.close);
});
} on _RollbackSignal {
return result;
}
return result;
}