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

如何清理调试带Rollback属性的单元测试后残留的环境事务

临时解决当前报错

你遇到的报错根源不在数据库层面,而是应用侧(测试运行进程)的.NET运行时残留了环境事务上下文、Db连接对象被标记为关联了未完成事务,所以你查数据库事务、重启数据库都没用,按以下步骤清理:

  • 完全关闭当前运行的IDE(Visual Studio/Rider等),结束所有测试宿主相关的后台进程
  • 删除测试项目下的bin、obj目录,重新编译整个解决方案即可恢复正常

根本原因与永久修复

你自定义的Rollback特性存在异步兼容问题,才会导致调试时出现事务残留:

  1. 修复TransactionScope异步支持
    默认构造的TransactionScope不支持异步上下文流转,在异步测试方法中使用时,await后事务上下文会丢失,AfterTest里的Dispose无法正确清理事务。修改Rollback类的构造逻辑:
public class Rollback : Attribute, ITestAction
{
    private TransactionScope transaction;

    public void BeforeTest(ITest test)
    {
        // 新增TransactionScopeAsyncFlowOption.Enabled支持异步上下文流转
        transaction = new TransactionScope(
            TransactionScopeOption.Required,
            TransactionManager.MaximumTimeout,
            TransactionScopeAsyncFlowOption.Enabled
        );
    }

    public void AfterTest(ITest test)
    {
        transaction.Dispose();
    }

    public ActionTargets Targets => ActionTargets.Test;
}
  1. 修复仓储方法的潜在问题
    你的AddDictionaryType方法存在同步IO、SQL注入风险,也可能触发事务上下文异常:
  • 不要用字符串拼接FromSqlRaw的SQL语句,存在SQL注入风险
  • FromSqlRaw返回的IQueryable直接调用同步Any()会触发同步IO,破坏异步事务上下文,改用EF Core异步LINQ查询:
public async Task AddDictionaryType(string name, string description)
{
    try
    {
        var hasSameName = await _dbContext.DictionaryTypes.AnyAsync(d => d.Name == name);
        var hasSameDescription = await _dbContext.DictionaryTypes.AnyAsync(d => d.Description == description);
        if (hasSameName || hasSameDescription)
        {
            throw new AddingExistingDictionaryException();
        }
        _dbContext.Add(new DictionaryType(name, description));
        await _dbContext.SaveChangesAsync();
    }
    catch (Exception ex)
    {
        throw ex;
    }            
}
  1. 调试注意事项
    如果需要在测试断点处查询数据库表数据,不要直接查询,要么在SSMS的查询语句后加WITH (NOLOCK)读取脏数据,要么先手动释放当前事务再查询,避免锁表同时也不会触发事务残留。

内容的提问来源于stack exchange,提问作者Alter Fredo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:15:03