runInTransaction<T> method
- Future<
T> action()
inherited
Runs the given action within a transaction.
The transaction is automatically committed if the action completes successfully, or rolled back if an exception is thrown.
Datapod supports nested transactions by using database savepoints. If runInTransaction is called while already in a transaction, a savepoint is created, and the inner action is executed relative to it.
Uses Zones to propagate the transaction context across asynchronous gaps.
Implementation
@override
Future<T> runInTransaction<T>(Future<T> Function() action) async {
final existing = currentTransaction;
if (existing != null) {
// Already in a transaction, use a savepoint for nested transaction.
final savepointName =
'datapod_sp_${Zone.current.hashCode}_${DateTime.now().microsecondsSinceEpoch}';
await existing.createSavepoint(savepointName);
try {
final result = await action();
await existing.releaseSavepoint(savepointName);
return result;
} catch (e) {
await existing.rollbackToSavepoint(savepointName);
rethrow;
}
}
final transaction = await beginTransaction();
return await runZoned(
() async {
try {
final result = await action();
await transaction.commit();
return result;
} catch (e) {
await transaction.rollback();
rethrow;
}
},
zoneValues: {
_transactionZoneKey: transaction,
},
);
}