using System; using System.Data; using System.Data.Common; using System.Threading; using System.Threading.Tasks; namespace EntityFrameworkCore.Jet.Data { internal class JetTransaction : DbTransaction { private JetConnection? _connection; private bool _disposed; internal virtual DbTransaction WrappedTransaction { get; } protected JetTransaction() { } public JetTransaction(JetConnection connection, IsolationLevel isolationLevel) { _connection = connection; LogHelper.ShowCommandHeader($"\r\nvvv BeginTransaction ({isolationLevel})"); WrappedTransaction = connection.InnerConnection.BeginTransaction(isolationLevel); } public override void Commit() { if (_disposed) throw new ObjectDisposedException(nameof(JetTransaction)); LogHelper.ShowCommandHeader("--- Commit"); WrappedTransaction.Commit(); _connection.ActiveTransaction = null; } protected override DbConnection? DbConnection => _connection; public override IsolationLevel IsolationLevel => WrappedTransaction.IsolationLevel; public override void Rollback() { if (_disposed) throw new ObjectDisposedException(nameof(JetTransaction)); LogHelper.ShowCommandHeader("^^^ Rollback"); WrappedTransaction.Rollback(); _connection.ActiveTransaction = null; } protected override void Dispose(bool disposing) { try { if (disposing) { if (_connection?.ActiveTransaction == this) { if (Connection.State == ConnectionState.Open) { Rollback(); } _connection.ActiveTransaction = null; } } } finally { _disposed = true; _connection = null; base.Dispose(disposing); } } public override Task CommitAsync(CancellationToken cancellationToken = new CancellationToken()) { if (_disposed) throw new ObjectDisposedException(nameof(JetTransaction)); return base.CommitAsync(cancellationToken); } public override ValueTask DisposeAsync() { if (_disposed) throw new ObjectDisposedException(nameof(JetTransaction)); return base.DisposeAsync(); } public override Task RollbackAsync(CancellationToken cancellationToken = new CancellationToken()) { if (_disposed) throw new ObjectDisposedException(nameof(JetTransaction)); return base.RollbackAsync(cancellationToken); } } }