[CSHARP-2473] Multiple startTransaction: true for simultaneous operations Created: 08/Jan/19  Updated: 27/Oct/23  Resolved: 09/Jan/19

Status: Closed
Project: C# Driver
Component/s: Transactions
Affects Version/s: 2.7.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Ivan Artemov Assignee: Unassigned
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 10


Attachments: Text File Program.cs    
Issue Links:
Problem/Incident
causes CSHARP-2476 Update documentation to be clear that... Backlog
Related
is related to SERVER-34052 Require 'startTransaction':true on fi... Closed

 Description   

When we need to use code like this:

var userId = @event.UserId;
 
await Task.WhenAll(
 CreateInitialSettings(userId),
 CreateWidgets(userId),
 CreatePersonalGroup(userId),
 CreateIncomingMessage(userId)
); 

causes error: Cannot specify 'startTransaction' on transaction 1 since it is already in progress.

All this operations go to Mongo with startTransaction: true argument, but only first operation must use this option.

This very strange behaviour in Server API and looks like crutch. (as it looks now)

Why we use session.StartTransaction() and operations must known about transaction ? Why this logic leaked from sessions to operations?

This bug is not driver bug, but you need to fix it on your side.



 Comments   
Comment by Ivan Artemov [ 09/Jan/19 ]

I understand, but my questions is why 2 independent operations depend on it run order? 

Why session transaction logic leaked to operation layer?

It normal code for many systems, i don't want change operation order, because MongoDB driver can't work with unordered method calling.

 

Comment by Dmitry Lukyanov (Inactive) [ 09/Jan/19 ]

Session is not multi-thread safe. Using the same session in two parallel Tasks results in this error because both Tasks think they are the first operation in the transaction. So, this code works as designed.

Comment by Ivan Artemov [ 09/Jan/19 ]

Unhandled Exception: MongoDB.Driver.MongoCommandException: Command insert failed: Cannot specify 'startTransaction' on transaction 1 since it is already in progress..
   at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ProcessResponse(ConnectionId connectionId, CommandMessage responseMessage)
   at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ExecuteAsync(IConnection connection, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocolAsync[TResult](IWireProtocol`1 protocol, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.RetryableWriteOperationExecutor.ExecuteAsync[TResult](IRetryableWriteOperation`1 operation, RetryableWriteContext context, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.BulkUnmixedWriteOperationBase`1.ExecuteBatchAsync(RetryableWriteContext context, Batch batch, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.BulkUnmixedWriteOperationBase`1.ExecuteBatchesAsync(RetryableWriteContext context, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation.ExecuteBatchAsync(RetryableWriteContext context, Batch batch, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation.ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
   at MongoDB.Driver.OperationExecutor.ExecuteWriteOperationAsync[TResult](IWriteBinding binding, IWriteOperation`1 operation, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.ExecuteWriteOperationAsync[TResult](IClientSessionHandle session, IWriteOperation`1 operation, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.BulkWriteAsync(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionBase`1.InsertOneAsync(TDocument document, InsertOneOptions options, Func`3 bulkWriteAsync)
   at TestApplication.Program.Main(String[] args) in D:\Projects\TestApplication\TestApplication\TestApplication\Program.cs:line 24
   at TestApplication.Program.<Main>(String[] args)

Comment by Ivan Artemov [ 09/Jan/19 ]

I attach 100% reproducable example for .NET Core 2.2 application (sorry, that not Github)

class Program
{
    static async Task Main(string[] args)
    {
        var client = new MongoClient("mongodb://127.0.0.1:27017");
 
        var database = client.GetDatabase("TestDb");
 
        using (var session = await client.StartSessionAsync())
        {
            session.StartTransaction();
 
            await Task.WhenAll(
                WriteA(database, session),
                WriteB(database, session)
            );
 
            await session.CommitTransactionAsync();
        }
        
        Console.Read();
    }
 
    private static Task WriteA(IMongoDatabase db, IClientSessionHandle session)
    {
       return db.GetCollection<CollectionAEntity>("CollectionA").InsertOneAsync(session, new CollectionAEntity
       {
           Name = "SomeStringA"
       });
    }
 
    private static Task WriteB(IMongoDatabase db, IClientSessionHandle session)
    {
        return db.GetCollection<CollectionBEntity>("CollectionB").InsertOneAsync(session, new CollectionBEntity
        {
            Name = "SomeStringB"
        });
    }
}
 
public class CollectionAEntity
{
    public ObjectId Id { get; set; }
    
    public string Name { get; set; }
}
 
public class CollectionBEntity
{
    public ObjectId Id { get; set; }
    
    public string Name { get; set; }
}

 

Comment by Dmitry Lukyanov (Inactive) [ 09/Jan/19 ]

Dear ZOXEXIVO,

I wasn't able to reproduce the behavior which you described. Could you please provide more details about this issue like where is the session started in your example, where is the transaction started?

It would be really helpful if you could create a small Console application that reproduces this behavior.

Thank you.

Generated at Wed Feb 07 21:42:39 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.