NpgsqlTransaction.CheckDisposed throwing exception
See original GitHub issueSteps to reproduce
-> Initialize DbContext without using explicit transaction -> Calling SaveChanges will throw a ObjectDisposedException by name NpgsqlTransaction
The issue
Hello.
I’m trying to run the SaveChanges method with Entity Framework 6 but after updating Npgsql to version 5 an exception is thrown.
The curious thing is that when using transaction control manually, the exception is not thrown by Npgsql.
Could you please check.
Thanks
this code does not work
public async Task ActivateUser(int idUser, CancellationToken token = default) {
using var ctx = new PContexto();
try {
var usr = await ctx.Users.FindAsync(token, idUser);
if (usr == null) {
throw new Exception("User not found.");
}
usr.Active = true;
//exception is thrown here, but only after the commit is complete
await ctx.SaveChangesAsync(token);
}
catch {
throw;
}
}
this code works
public async Task ActivateUser(int idUser, CancellationToken token = default) {
using var ctx = new PContexto();
using var t = ctx.Database.BeginTransaction();
try {
var usr = await ctx.User.FindAsync(token, idUser);
if (usr == null) {
throw new Exception("User not found");
}
usr.Active = true;
await ctx.SaveChangesAsync(token);
t.Commit();
}
catch {
t.Rollback();
throw;
}
}
Entity Log:
Opened connection asynchronously at 27/04/2021 18:12:33 -03:00
Started transaction at 27/04/2021 18:12:33 -03:00
UPDATE “sis”.“table_name” SET “field”=@p_0 WHERE “id” = @p_1
– p_0: ‘False’ (Type = Boolean, IsNullable = false)
– p_1: ‘999’ (Type = Int32, IsNullable = false)
– Executing asynchronously at 27/04/2021 18:12:33 -03:00
– Completed in 5 ms with result: 1
Committed transaction at 27/04/2021 18:12:33 -03:00
Closed connection at 27/04/2021 18:12:33 -03:00
Exception thrown: ‘System.ObjectDisposedException’ in mscorlib.dll
Exception message:
It is not possible to access a discarded object. Object name: ‘NpgsqlTransaction’.
Stack trace:
at Npgsql.NpgsqlTransaction.CheckDisposed()
at Npgsql.NpgsqlTransaction.get_Connection()
at Npgsql.NpgsqlTransaction.get_DbConnection()
at System.Data.Common.DbTransaction.get_Connection()
at System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.Dispose(DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.EntityTransaction.Dispose(Boolean disposing)
at System.Data.Common.DbTransaction.Dispose()
at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__156`1.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStoreAsync>d__154.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesInternalAsync>d__151.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Opm.Data.Utils.Repositorio.RepositorioBase`2.<UpdateAsync>d__32.MoveNext() in D:\Sources\Extensions\OP.Data.Utils\Repositorio\RepositorioBase.cs:line 650
Further technical details
Npgsql version: 5.0.4.0 PostgreSQL version: 13.0 Operating system: CentOS 8
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (7 by maintainers)
The problem is with unbinding of the transaction - with the pooled connection we unbind it every time a connection is returned to the pool, but we do not do the same for the unpooled ones.
Thanks @tnering. In general, the EF6 provider is pretty much “archived” and we don’t test it with newer versions of Npgsql; so my recommendation would be to not necessarily upgrade that, unless you have a very specific problem you’re looking to solve. I’m mainly interested in case it exposes a bug in Npgsql itself.