Cant use opened transaction in Entitiframework 6.1.3 with PostgreSQL

1

I have been trying to use EntityFramework6.Npgsql with transaction, but I'm getting above exception when I call the method DbContext.UseTransaction.

Error Message (Latest InnerException):

"Npgsql.PostgresException (0x80004005): 25P02: current transaction is aborted, commands ignored until end of transaction block"

So, I created a new project to simulate and try out to find what was causing the problem.

Test Code

try
{
    using (var conn = new Npgsql.NpgsqlConnection(ConfigurationManager.AppSettings["app:pgconn"]))
    {
        conn.Open();
        using (var transaction = conn.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
        {
            using (var ctx = new CadastrosContext(conn))
            {
                var tenant = new Tenant();
                ctx.Database.UseTransaction(transaction);
                ctx.Tenants.Add(tenant);
                await ctx.SaveChangesAsync()
                    .ConfigureAwait(false);
                Debug.WriteLine($"Tenant 1 Id: {tenant.TenantId}");
            }
            using (var ctx = new CadastrosContext(conn))
            {
                var tenant = new Tenant();
                ctx.Database.UseTransaction(transaction);
                ctx.Tenants.Add(tenant);
                await ctx.SaveChangesAsync()
                    .ConfigureAwait(false);
                Debug.WriteLine($"Tenant 2 Id: {tenant.TenantId}");
            }
            await transaction.CommitAsync();
        }
    }
}
catch (Exception ex)
{
    throw;
}  

Packages

package id="EntityFramework" version="6.1.3" targetFramework="net462"
package id="EntityFramework6.Npgsql" version="3.1.1" targetFramework="net462"
package id="Npgsql" version="3.1.2" targetFramework="net462"

The most strange behavior is that when I call the action the second time it works!! After hours investigating the root of the problem (using others databases the code works as expected), I finded out that when I switch to first version of EF6 it works normally.

Packages that works

package id="EntityFramework" version="6.1.0" targetFramework="net462"
package id="EntityFramework6.Npgsql" version="3.1.1" targetFramework="net462"
package id="Npgsql" version="3.1.2" targetFramework="net462"

Anyone had this problem too?? There is a bug that the Npgsql/EntityFramework6.Npgsql does not supports the new version of EntityFramework?

asp.net-mvc
postgresql
asp.net-web-api
entity-framework-6
asked on Stack Overflow May 21, 2017 by Maicon Matsubara • edited Oct 7, 2018 by S-Man

1 Answer

1

I've run into the same problem today, and the only thing i could find was your question. :)

First query to the database always fails with error: the current transaction is aborted, the commands until the end of the transaction block are ignored.

In my case PostgreSQL logs looks like this:

2019-07-15 14: 43: 40.260 +07 [12364] ERROR: the relation "dbo.EdmMetadata" does not exist (symbol 51)
2019-07-15 14: 43: 40.260 +07 [12364] OPERATOR: SELECT "Extent1". "Id", "Extent1". "ModelHash" FROM "dbo". "EdmMetadata" AS "Extent1" ORDER BY "Extent1" . "Id" DESC LIMIT 1
2019-07-15 14: 43: 40.649 +07 [12364] ERROR: the current transaction is aborted, the commands until the end of the transaction block are ignored
2019-07-15 14: 43: 40.649 +07 [12364] OPERATOR: DELETE FROM "MS". "MessageReference" WHERE E'T '= "Mark"

Before executing my query, EF tries to get data from not existing table dbo.EdmMetadata, the query fails and transaction is not commited. This query is needed to compare hash of the model that was used to create database with your current model. But if you used Code First with existing database this table doesn't exist.

To avoid this error you could disable model hash check by setting null to the database initializator

static YourContext()
{
   System.Data.Entity.Database.SetInitializer<BaseDynamicDbContext>(null);
}

In my case I needed initializator to migrate to the latest version on application start, so I've created the empty dbo.EdmMetadata table, to prevent first query error.

create table "dbo"."EdmMetadata"
(
  "Id"        integer not null
    constraint "PK_EdmMetadata"
    primary key,
  "ModelHash" varchar(50)
);
answered on Stack Overflow Jul 15, 2019 by VladaxLe • edited Jul 15, 2019 by VladaxLe

User contributions licensed under CC BY-SA 3.0