EF Core Nested Transaction

纪录一下目前解法( EF Core 3.1 适用,其他版本尚未试过 )

实作 IDbContextTransactionManager:Begin/Commit 时计算层数,最外层才真的 Commit
   public class NestedTransactionManager : IDbContextTransactionManager{    readonly ISqlServerConnection _sqlServerConnection;    public NestedTransactionManager(ISqlServerConnection sqlServerConnection)    {        // Dependency inject ISqlServerConnection, ISqlServerConnection is original IDbContextTransactionManager in EF Core 3.1 .        _sqlServerConnection = sqlServerConnection;    }    int Layer = 0;    public IDbContextTransaction CurrentTransaction        => _sqlServerConnection.CurrentTransaction;    public IDbContextTransaction BeginTransaction()    {        if (Layer++ == 0)            _sqlServerConnection.BeginTransaction();        return new NestedTransation(this, Layer);    }    public async Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken = default)    {        if (Layer++ == 0)            await _sqlServerConnection.BeginTransactionAsync(cancellationToken);        return new NestedTransation(this, Layer);    }    public void CommitTransaction()    {        if (Layer-- <= 1)            _sqlServerConnection.CommitTransaction();    }    public Task CommitTransactionAsync(CancellationToken cancellationToken = default)        => Layer-- <= 1        ? _sqlServerConnection.CurrentTransaction.CommitAsync(cancellationToken)        : Task.CompletedTask;            public void ResetState()        => _sqlServerConnection.ResetState();    public Task ResetStateAsync(CancellationToken cancellationToken = default)        => _sqlServerConnection.ResetStateAsync(cancellationToken);    public void RollbackTransaction()        => _sqlServerConnection.RollbackTransaction();}
class NestedTransation : IDbContextTransaction{    readonly NestedTransactionManager _manager;    readonly int _layer;    public NestedTransation(NestedTransactionManager manager, int layer)    {        _manager = manager;        _layer = layer;    }    bool Commited => _layer > _manager.Layer;    public Guid TransactionId        => Transaction.TransactionId;    IDbContextTransaction Transaction        => _manager.CurrentTransaction;    public void Commit()        => _manager.CommitTransaction();    public Task CommitAsync(CancellationToken cancellationToken = default)        => _manager.CommitTransactionAsync(cancellationToken);    public void Dispose()    {        if (!Commited && Transaction != null)            Transaction.Dispose();    }    public ValueTask DisposeAsync()        => !Commited && Transaction != null        ? Transaction.DisposeAsync()        : default;    public void Rollback()        => Transaction.Rollback();    public Task RollbackAsync(CancellationToken cancellationToken = default)        => Transaction.RollbackAsync(cancellationToken);}
Startup 取代 Service
services.AddDbContext<AppDbContext>(options =>{    ...    options.ReplaceService<IDbContextTransactionManager, NestedTransactionManager>();});

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章