C#C
C#2y ago
no >> body

✅ EF core transactions in PostgreSQL

I have a custom extension method for running operations on DbContext.
One is for running operations in transactions with a specific isolation level, and the second one is for retry logic.
The problem I just spotted is that isolation doesn't work properly, despite having enough retries and time to process transactions.
I have an entity called WalletBalance that contains a property Amount.
And here is my job for testing:
[DisallowConcurrentExecution]
public class TestJob(ILogger<TestJob> logger, MasterDbContext masterDbContext, IServiceScopeFactory factory) : IJob
{
    private Guid WalletBalanceId { get; set; }

    public async Task Execute(IJobExecutionContext context)
    {
        WalletBalanceId = masterDbContext.WalletBalances.First(x => x.Amount == 0).Id;

        var tasks = new List<Task>
        {
            UpdateBalance(100, 100),
            UpdateBalance(-100, 100),
            UpdateBalance(100, 100),
            UpdateBalance(-100, 100)
        };

        await Task.WhenAll(tasks);
    }

    private async Task UpdateBalance(int amount, int times)
    {
        using IServiceScope scope = factory.CreateScope();
        MasterDbContext context = scope.ServiceProvider.GetRequiredService<MasterDbContext>();

        for (var i = 0; i < times; i++)
        {
            await context.ExecuteInCustomStrategyAsync(
                async _ =>
                {
                    await context.ExecuteInTransactionAsync(
                        async _ =>
                        {
                            WalletBalance walletBalance = (await context.WalletBalances.FindAsync(WalletBalanceId))!;
                            walletBalance.Amount += amount;
                        });
                });
        }
    }
}

I expect the amount to be 0 after all the transactions have been run. But in fact Amount has random numbers after each run of the job.
My implementation of ExecuteInCustomStrategyAsync and ExecuteInTransactionAsync below
Was this page helpful?