-
Notifications
You must be signed in to change notification settings - Fork 191
Closed
Description
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
- Run the provided code with an Oracle database where the user does not have permission to create a table.
- Observe that an ORA-01031 exception is thrown.
- 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
Metadata
Metadata
Assignees
Labels
No labels