如何快速回滚端到端测试在SQL Server数据库中产生的数据变更?
实际使用经验结论
我们团队在自动化测试流程中使用RESTORE DATABASE FROM DATABASE_SNAPSHOT做数据回滚已经3年,完全可以满足你提到的每次测试用同一套初始数据的需求,是比truncate全表重导数据优雅得多的方案。
恢复速度相关
恢复速度仅取决于快照创建后产生的变更数据量,和快照创建时的原始数据库体量没有关系。
我们的测试场景下,初始业务库大小为12GB,每次端到端测试产生的数据变更在300M600M区间,单次恢复耗时稳定在715秒,比之前用的truncate全表+批量导入初始数据的方案快了85%以上,原来的方案每次要耗时1分钟以上。
使用注意事项
- 首先确认你的SQL Server版本支持快照功能:仅企业版、开发版支持数据库快照,标准版无此功能
- 创建初始快照前要保证数据库处于完全干净的初始状态,没有未提交的事务,建议创建时临时将数据库设为单用户模式,避免建快照过程中有数据写入导致初始状态不一致
- 执行恢复操作前必须杀掉所有连接到目标测试库的会话,否则恢复命令会报错,你可以在自动化脚本中加入以下逻辑先批量杀会话:
DECLARE @kill varchar(8000) = ''; SELECT @kill = @kill + 'KILL ' + CONVERT(varchar(5), spid) + ';' FROM master.dbo.sysprocesses WHERE dbid = DB_ID('你的测试库名称') EXEC(@kill); -- 执行恢复 RESTORE DATABASE 你的测试库名称 FROM DATABASE_SNAPSHOT = '你预先创建的初始快照名称';
- 快照文件会存储所有变更数据页的原始副本,测试运行过程中产生的变更越多,快照占用的磁盘空间越大,但每次执行恢复操作后快照会自动重置到初始状态,不会出现磁盘占用无限上涨的问题
- 该方案不需要处理表之间的外键依赖:truncate全表的方案经常因为外键关联需要严格控制删表顺序,后续表结构调整后还要同步更新清理脚本,维护成本很高,快照回滚完全不需要考虑这类问题。
若使用SQL Server标准版的替代方案
如果你用的是不支持快照的标准版,可以选择更轻量的方案:测试执行前开启一个全局显式事务,所有测试操作都在这个事务内执行,测试完成后直接执行ROLLBACK回滚所有变更,这个方案回滚速度极快,仅适合单会话串行执行的测试场景,多并发测试下容易出现锁冲突。
内容的提问来源于stack exchange,提问作者Jakub Janiš
相关产品推荐
相关产品推荐

