You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向正在运行的TransactionScope登记并获取事务提交、回滚通知?

向TransactionScope登记自定义事务资源的实现方案

核心实现思路

你需要实现.NET提供的IEnlistmentNotification接口,将自定义的事务资源登记到当前环境事务中,就能自动接收事务的提交、回滚通知。

具体实现步骤

1. 实现自定义事务登记类

这个类需要继承IEnlistmentNotification,封装你自己的事务提交、回滚逻辑:

public class ContosoTransactionEnlistment : IEnlistmentNotification
{
    // 保存你自己的事务实例,用来执行提交/回滚
    private readonly IContosoTransaction _tx;

    public ContosoTransactionEnlistment(IContosoTransaction tx)
    {
        _tx = tx;
    }

    // 事务管理器询问资源是否可以提交
    public void Prepare(PreparingEnlistment preparingEnlistment)
    {
        try
        {
            // 这里可以做你自己的预检查逻辑,确认可以提交
            preparingEnlistment.Prepared();
        }
        catch
        {
            // 预检查失败,通知事务回滚
            preparingEnlistment.ForceRollback();
        }
    }

    // 收到提交通知
    public void Commit(Enlistment enlistment)
    {
        _tx.Commit();
        // 通知事务管理器提交完成
        enlistment.Done();
    }

    // 收到回滚通知
    public void Rollback(Enlistment enlistment)
    {
        _tx.Rollback();
        // 通知事务管理器回滚完成
        enlistment.Done();
    }

    // 事务状态不确定时触发(比如事务管理器故障)
    public void InDoubt(Enlistment enlistment)
    {
        // 按自己的业务需求处理,一般默认回滚也可以
        _tx.Rollback();
        enlistment.Done();
    }
}

2. 在业务方法中自动检测环境事务并登记

修改你对外暴露的业务方法,自动判断当前是否有运行中的TransactionScope环境事务,按需登记:

public class TurboEncabulator
{
    public void UpendCardinalGrammeters()
    {
        IContosoTransaction tx = null;
        // 检测是否存在环境事务
        var ambientTx = Transaction.Current;
        if (ambientTx != null)
        {
            // 开启你自己的事务
            tx = BeginTransaction();
            // 将自定义事务登记到环境事务中
            // 如果是易失资源(比如内存操作)用EnlistVolatile,持久化资源用EnlistDurable
            ambientTx.EnlistVolatile(new ContosoTransactionEnlistment(tx), EnlistmentOptions.None);
        }

        try
        {
            // 这里写你的正常业务逻辑
            // ......
        }
        catch
        {
            // 如果没有环境事务,自行回滚
            tx?.Rollback();
            throw;
        }

        // 如果没有环境事务,自行提交
        if (ambientTx == null)
        {
            tx?.Commit();
        }
    }

    // 你原有开启事务的方法
    private IContosoTransaction BeginTransaction()
    {
        // 原有逻辑实现
    }
}

补充说明

  • 如果你的自定义资源是内存类的易失资源,直接用EnlistVolatile即可;如果是磁盘存储类的持久化资源,需要支持故障恢复,就使用EnlistDurable方法登记。
  • 可选实现ISinglePhaseNotification接口代替IEnlistmentNotification,可以在单阶段提交场景下优化性能,减少不必要的交互。

内容的提问来源于stack exchange,提问作者Ian Boyd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 00:15:03