我对交易处理的需求有点不寻常。
我正在为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
是否有一种方法可以确保我最终始终可以回滚到初始状态?我必须考虑到用户可以调用可能嵌套的并且都可以包含事务处理语句的存储过程/触发器。使用我所有的解决方案,当用户在测试代码中使用回滚tran时,他们就逃脱了事务,并且不会清除所有内容
我想要的是,如果用户调用回滚,则仅回滚他们的部分事务,并且在测试初始化之前我启动的事务仍然完好无损。
如果有可能,我想防止强迫我的用户使用事务模板,该模板在存在事务时使用保存点。
答案 0 :(得分:0)
如果没有用户代码的任何通信/规则,我认为这是不可能的。尽管您做了什么,但是如果用户的代码运行的COMMIT
数量与当时的@@TRANCOUNT
一样多,则将提交事务,您将无能为力。
执行此操作的一种方法是,检查/强制执行用户代码,而不是使用COMMIT
,而是将其更改为if @@TRANCOUNT>=2 COMMIT
。这将确保只能通过您的COMMIT
命令完成TRUE数据提交。当然,您确实不想提交,所以您只需rollback
就可以了。
您提到:
我想要的是,如果用户仅调用回滚, 交易被回滚
请注意,嵌套交易是一种神话。请参阅this excellent article。长话短说:“嵌套” BEGIN TRANSACTION
和COMMIT
实际上除了改变系统变量@@TRANCOUNT
的值外实际上什么也不做,因此可以通过过程来建立某些组织。
答案 1 :(得分:0)
我认为不可能回滚一部分交易并保持另一笔交易不变。我们回滚事务的那一刻,整个事务都会回滚。
答案 2 :(得分:0)
SQL Server指出,SQL Server不支持其他嵌套事务。我决定在用户代码之后尽量减少状态更改语句的数量,并在测试批处理开始时清理这些语句。这样一来,我就不能回滚自己的事务,这并不重要,因为繁重的工作将由我或用户回滚。
当起始@@ TRANCOUNT和结束@@ TRANCOUNT不匹配时,我还决定通过测试,以便在用户事务出现问题时无法通过任何测试。
但是,当前系统仍将与用户进行COMMIT TRAN斗争。这又是一个问题。
答案 3 :(得分:0)
我认为实际需要是为T-SQL编写测试用例。如果那是正确的话,那么我觉得您不必重新发明轮子并开始使用开源测试框架T-SQLT https://tsqlt.org/