SQL Server 如何始终回滚整个事务

标签 sql sql-server tsql testing transactions

我对交易处理有一些不同寻常的需求。

我正在为 SQL Server 开发一个突变测试框架,为此我需要在一个事务中运行我的测试,以便数据库在测试完成时始终处于它开始时的状态。

但是我有一个问题,用户可以在测试过程中编写代码,并且可以调用可能在也可能不在(嵌套)事务(保存点)内的rollback transaction

高层看起来像这样

start transaction
initialize test
run test with user code
   may or may not contain:
      - start tran
      - start tran savename
      - commit tran
      - commit tran savename
      - rollback tran
      - rollback tran savename
output testresults
rollback transaction

有没有办法确保我最终总能回滚到初始状态?我必须考虑到用户可以调用可能嵌套并且都可以包含事务语句的存储过程/触发器。使用我所有的解决方案,当用户在他们的测试代码中使用 rollback tran 时,他们会逃避交易,并不是所有的东西都会被清理

我想要的是,如果用户调用回滚,只有他们的事务部分被回滚,而我在测试初始化​​之前开始的事务仍然完好无损。

如果可能的话,我想防止在事务已存在时强制我的用户使用使用保存点的事务模板。

最佳答案

如果没有针对用户代码的任何通信/规则,我认为这是不可能的。不管你做什么,如果用户的代码运行了与当时 @@TRANCOUNT 一样多的 COMMIT,事务将被提交,你将无能为力做那个。

你可以这样做的一种方法是,如果你检查/强制用户代码,而不是使用 COMMIT,将其更改为 if @@TRANCOUNT>=2 COMMIT .这将确保 TRUE 数据提交只能通过您的 COMMIT 命令完成。当然,有时您真的不想提交,所以您只需rollback 就可以结束。

你提到:

What I want is that if a user calls rollback only their part of the transaction is rolled back

请注意嵌套事务是一种神话。引用this excellent article .长话短说:“嵌套”BEGIN TRANSACTIONCOMMIT 实际上除了更改系统变量 @@TRANCOUNT 的值外什么都不做一些组织可以通过程序进行。

关于SQL Server 如何始终回滚整个事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56804224/

相关文章:

python - 有没有一种方法可以将某些值的数据从另一个表插入到一个表中?

mysql - 如何显示数据库mysql中的最新记录

sql-server - sql中具有结束时间的当前日期

c# - 如何从 C# 中的数据库获取用户名和密码?

sql - 使用 DATEADD 和 DATEDIFF 获取一周的开始日(星期一)时出现问题

MySQL,两个表显示来自两个表的信息

sql - 在 MySQL 中按月和年分组

SQL解析键值字符串

mysql - 使用 OPENQUERY 语法通过链接服务器 (SQL Server 2005) 调用 MySQL 存储过程(带参数)的问题

SQL - 将长整数转换为日期时间