Skip to content

Changes committed despite active transaction and rollback in Oracle EF Core #445

@cdMOE

Description

@cdMOE

EDIT
Read comment

Hello,

I encountered a situation where changes to the database are committed despite an active transaction, even when an error occurs and RollbackTransaction() is called.

The following code demonstrates the issue:

public class Worker(ILogger<Worker> logger, IServiceScopeFactory serviceScopeFactory) : BackgroundService
{
    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        using var scope = serviceScopeFactory.CreateScope();
        var context = scope.ServiceProvider.GetRequiredService<MyContext>();

        var header = new Header
        {
            Id = 3,
            Data = "something"
        };

        context.Database.BeginTransaction();
        context.Headers.Add(header);
        context.SaveChanges();

        try
        {
            using var cmd = new OracleCommand(string.Empty, context.Database.GetDbConnection() as OracleConnection);
            var tablename = "sometable";
            
            // This will throw ORA-01031 (insufficient privileges)
            var createCommand = $"CREATE GLOBAL TEMPORARY TABLE {tablename} (something number)";
        
            cmd.CommandText = createCommand;
            cmd.ExecuteNonQuery();
        }
        catch (Exception e)
        {
            logger.LogError(e, "error");
            context.Database.RollbackTransaction();
            return Task.FromException(e);
        }

        context.Database.CommitTransaction();
        
        return Task.CompletedTask;
    }
}

Reproduction Steps

  1. Run the provided code with an Oracle database where the user does not have permission to create a table.
  2. Observe that an ORA-01031 exception is thrown.
  3. Check the database: the mytest_headers table still contains the inserted row.

Expected Behavior

Since a transaction was started using context.Database.BeginTransaction(), I expected the context.Headers.Add(header); operation to not be committed because:

  • The transaction was never explicitly committed.
  • RollbackTransaction() was called after the exception.

However, after inspecting the database, I see that the row was committed.

Reproducible Test Setup

Repro Project linked.

Table Creation

CREATE TABLE mytest_headers (
    ID NUMBER,
    Data VARCHAR2(50),
    PRIMARY KEY(Id)
);

Database User Setup

CREATE USER mytestuser IDENTIFIED BY mytest123;
GRANT CREATE SESSION TO mytestuser;
GRANT SELECT, INSERT ON mytest_headers TO mytestuser;

Environment

  • .net version: 8.0
  • Microsoft.EntityFrameworkCore Version 8.0.14
  • Oracle.EntityFrameworkCore Version 8.23.70
  • Oracle.ManagedDataAccess.Core" Version 23.7.0
  • Oracle DB Version: 19

ReproOracleCommand.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions