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

如何回滚连续API调用产生的数据库操作以助力自动化测试?

自动化测试中跨API数据库操作的回滚方案(C#/TypeScript)

后端(C#)实现方案

1. 事务ID绑定会话方案

这是最贴合需求的方案,核心思路是用唯一事务ID把多个独立API的数据库操作绑定到同一个事务中:

  • 新增三个测试专用接口:
    • 创建事务接口:生成唯一transactionId,开启数据库事务并将事务对象与ID绑定存储(比如用ConcurrentDictionary<string, IDbContextTransaction>做内存缓存),返回ID给前端。
    • 提交事务接口:根据传入的transactionId找到对应事务,执行提交并清理缓存。
    • 回滚事务接口:根据传入的transactionId找到对应事务,执行回滚并清理缓存。
  • 改造现有Insert/Update/Delete API,添加transactionId参数,接口内部通过ID获取共享事务,用该事务执行数据库操作。

示例代码(EF Core):

// 全局缓存存储事务,仅测试环境使用
private static readonly ConcurrentDictionary<string, IDbContextTransaction> _transactionCache = new();

// 创建事务接口
[HttpPost("test/create-transaction")]
public IActionResult CreateTestTransaction()
{
    var transaction = _dbContext.Database.BeginTransaction();
    var transactionId = Guid.NewGuid().ToString();
    _transactionCache.TryAdd(transactionId, transaction);
    // 设置超时自动清理,避免连接泄漏
    _ = Task.Delay(TimeSpan.FromMinutes(10)).ContinueWith(_ =>
    {
        if (_transactionCache.TryRemove(transactionId, out var tx))
        {
            tx.Rollback();
            tx.Dispose();
        }
    });
    return Ok(new { TransactionId = transactionId });
}

// 改造后的Insert API
[HttpPost("data/insert")]
public async Task<IActionResult> InsertData([FromBody] DataDto dto, [FromQuery] string? transactionId)
{
    IDbContextTransaction? transaction = null;
    var useSharedTransaction = !string.IsNullOrEmpty(transactionId) && _transactionCache.TryGetValue(transactionId, out transaction);
    
    try
    {
        _dbContext.Data.Add(new DataEntity { Name = dto.Name, Value = dto.Value });
        if (useSharedTransaction)
        {
            await _dbContext.SaveChangesAsync();
        }
        else
        {
            // 非测试场景仍用独立事务
            await using var localTx = await _dbContext.Database.BeginTransactionAsync();
            await _dbContext.SaveChangesAsync();
            await localTx.CommitAsync();
        }
        return Ok();
    }
    catch
    {
        transaction?.Rollback();
        return StatusCode(500);
    }
}

// 提交事务接口
[HttpPost("test/commit-transaction")]
public IActionResult CommitTransaction([FromQuery] string transactionId)
{
    if (_transactionCache.TryRemove(transactionId, out var transaction))
    {
        try
        {
            transaction.Commit();
            transaction.Dispose();
            return Ok();
        }
        catch
        {
            transaction.Rollback();
            transaction.Dispose();
            return StatusCode(500);
        }
    }
    return BadRequest("无效的事务ID");
}

2. 数据库快照/恢复方案

如果不想改动现有API,可以在自动化测试流程中加入数据库快照操作:

  • 测试用例执行前,对测试数据库创建快照。
  • 测试结束后,不管成功或失败,都将数据库恢复到快照状态。
  • 优点:无需修改API,适合快速搭建测试环境;缺点:并行测试会互相干扰,快照恢复耗时较长,仅适合单线程测试场景。

前端(TypeScript)配合实现

前端无法直接控制数据库事务,主要负责在测试脚本中串联事务流程:

import axios from 'axios';

async function executeTestCase() {
    let transactionId: string | undefined;
    try {
        // 1. 开启测试事务
        const txResp = await axios.post('/api/test/create-transaction');
        transactionId = txResp.data.transactionId;

        // 2. 依次调用三个操作API,携带事务ID
        await axios.post('/api/data/insert', { name: "test", value: 123 }, { params: { transactionId } });
        await axios.post('/api/data/update', { id: 1, value: 456 }, { params: { transactionId } });
        await axios.post('/api/data/delete', { id: 1 }, { params: { transactionId } });

        // 3. 测试通过,提交事务
        await axios.post('/api/test/commit-transaction', undefined, { params: { transactionId } });
    } catch (error) {
        // 4. 测试失败,回滚事务
        if (transactionId) {
            await axios.post('/api/test/rollback-transaction', undefined, { params: { transactionId } });
        }
        throw error; // 抛出错误标记测试失败
    }
}

安全问题分析

  • 事务ID泄露风险:使用随机GUID作为事务ID,泄露概率极低,但需确保测试专用接口仅对测试环境开放,可通过IP白名单、测试专用API密钥验证限制访问。
  • 数据库连接泄漏:必须给事务设置超时自动清理逻辑,避免因测试脚本异常导致事务长期占用数据库连接。
  • 生产环境误操作:测试专用接口必须与生产环境隔离,禁止部署到生产环境,或在代码中加入环境判断,仅在测试环境启用这些接口。
  • 数据一致性:共享事务期间,其他操作访问该数据会出现锁等待,测试环境需确保无其他业务流量干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:25:30