I see you have already applied `using` to the transaction. But given that a new `SqlConnection` is created for each command, I would suggest wrapping it in a `using` statement as well. private async Task<T> CommandAsync<T>(Func<IDbConnection, IDbTransaction, int, Task<T>> command) { using(var connection = new SqlConnection(_connectionStrings.CurrentValue.MainDatabase)) { await connection.OpenAsync().ConfigureAwait(false); using var transaction = await connection.BeginTransactionAsync(); try { T result = await command(connection, transaction, 300).ConfigureAwait(false); await transaction.CommitAsync().ConfigureAwait(false); return result; } catch (Exception ex) { await transaction.RollbackAsync().ConfigureAwait(false); _logger.LogError(ex, "Rolled back transaction"); throw; } } }