Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use MongoDB ClientSessions & Transactions in C# async code?

From the docs Read isolation consistency - Sessions (emphasis mine)

To provide causal consistency, MongoDB 3.6 enables causal consistency in client sessions. A causally consistent session denotes that the associated sequence of read and acknowledged write operations have a causal relationship that is reflected by their ordering. Applications must ensure that only one thread at a time executes these operations in a client session.

From the docs Transactions - Transactions & Sessions

Transactions are associated with a session. That is, you start a transaction for a session. At any given time, you can have at most one open transaction for a session.

  1. Does this say it is unsafe to use async/await, or at least that all the tasks using the session and transaction should - somehow - execute on on the same thread?

  2. Or does it say that the each async operation on the session needs to complete before another can be started?

  3. Or does it say that there can be multiple async operations running against the session, but all of those operations must be running on the same thread.

tl;dr
Is it safe to use async/await with transactions? If not, what is the best practice here?

e.g. Is this (admittedly horrible code) OK?

[HttpPost]
public async Task<IActionResult> PostAsync(CreateRequest createRequest)
{
    using (var session = await _client.StartSessionAsync())
    {
        await session.StartTransactionAsync();

        var inserts = new Task[] {
            _colHomer.InsertOneAsync(session, createRequest.Homer),
            _colMarge.InsertOneAsync(session, createRequest.Marge),
            _colBart.InsertOneAsync(session, createRequest.Bart)
        };

        await Task.WhenAll(inserts);

        await session.CommitTransactionAsync();
    }
}
like image 448
Binary Worrier Avatar asked Nov 18 '22 05:11

Binary Worrier


1 Answers

Transaction and sessions are designed to be not thread safe. I think the above code will work, but it's not guarantied for all cases. UPDATE: however it's definitely save to use session/transaction in regular async way (without any manual task waiting and similar logic).

like image 165
dododo Avatar answered Dec 23 '22 15:12

dododo