In a web service, I am querying a SQL Server 2016 database. Using a .NET TransactionScope as follows to keep transaction management in my service layer but data queries/commands in my data layer ("store" classes) code, we have a few places that follow this pattern:
using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
bool needsInsert = await store1.Exists(request.id);
if (needsInsert) mainRowsUpdatedCount = await store2.Insert(request);
transaction.Complete();
}
Each of those "store" methods follow this pattern (using Dapper, though I suspect it doesn't matter):
const string query = @"SELECT ..."; // or INSERT or MERGE as the case may be
using IDbConnection connection = new SqlConnection(ConnectionString.Value);
return await connection.QueryAsync<T>(query, new { ... }); // or connection.ExecuteAsync as the case may be
This works great on most calls, but sometimes I get the following (though quite rarely):
System.PlatformNotSupportedException: This platform does not support distributed transactions.
So could it be that, in the above example, store1.Exists runs, gets a connection, enlists it in the transaction, runs its query, closes, then sometimes before store2.Insert can run, some other unrelated thread gets the same connection from the connection pool that already has an open transaction, attempts to run a query and thus throws a PlatformNotSupportedException, since .NET Core (or .NET 5+) doesn't support distributed transactions?
If so, how can I overcome this without passing my connections around?
If not, what else could be causing this exception?