You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Using TransactionScope and EF together with raw connection might trigger idle-in-transaction timeout #3602
I have a piece of code where I use both DbContext and data source to get raw sql connection, and in together with TransactionScope, it triggers idle-in-transaction timeout.
Here's a unit test that I put in TransactionNpgsqlTest class to reproduce it. If we "ping" DbContext every now and then this test passes. If we comment out the first context usage, it also passes, but if we leave it in current state, you should experience the timeout (mine is set to 5 seconds).
My expectation would be that no matter in which connection, the transaction is the same and no timeout should be triggered.
Also, prepared transaction count check is there to ensure that no distributed transaction is being used.
P.S. I am not sure if this is more of Npgsql problem or EF itself, but trying to start here.
[ConditionalFact]publicasyncTaskAmbient_transaction_bug(){awaitusingvarcontext=CreateContext();vartimeoutInMilliseconds=awaitcontext.Database.SqlQueryRaw<int>("SELECT setting::INTEGER AS \"Value\" FROM pg_settings WHERE name = 'idle_in_transaction_session_timeout'").Order().FirstAsync();Assert.True(timeoutInMilliseconds>0);timeoutInMilliseconds/=2;usingvartransactionScope=newTransactionScope(TransactionScopeOption.Required,TransactionScopeAsyncFlowOption.Enabled);// Adding this line causes "terminating connection due to idle-in-transaction timeout" error at the bottom. Feels like transactions are not scoped._=context.Set<TransactionCustomer>().Any();awaitusing(varconn=newNpgsqlConnection(TestStore.ConnectionString)){conn.Open();for(vari=0;i<3;i++)// A loop to show that this does not invoke transaction session timeout when doing some "work" in the same connection{awaitusingvarcmd=newNpgsqlCommand("SELECT 1",conn);cmd.ExecuteNonQuery();// Uncommenting this Assert would NOT cause the idle-in-transaction timeout anymore, because it "pings" EF transaction.//Assert.Equal(0, GetNumberOfPreparedTransactions(context));awaitTask.Delay(timeoutInMilliseconds);}}_=context.Set<TransactionCustomer>().Any();Assert.Equal(0,GetNumberOfPreparedTransactions(context));}intGetNumberOfPreparedTransactions(DbContextcontext)=>context.Database.SqlQueryRaw<int>("SELECT COUNT(*) AS \"Value\" FROM pg_prepared_xacts WHERE database = 'postgres'").Order().First();
Activity