我有一个名为 MoveSomeItems 的 sp,它从 Foo Db 的 tableA 中获取一些行。并将它们移动到 Bar Db 中的 tableA。
我想测试这个 sp 如果它真的移动了这些项目。
在事务中运行这个 sp 并选择行以查看它们是否被移动是否足够,或者我应该以不同的方式处理它?
我有一个名为 MoveSomeItems 的 sp,它从 Foo Db 的 tableA 中获取一些行。并将它们移动到 Bar Db 中的 tableA。
我想测试这个 sp 如果它真的移动了这些项目。
在事务中运行这个 sp 并选择行以查看它们是否被移动是否足够,或者我应该以不同的方式处理它?
这取决于这一切出错的影响是什么?目标表中的数据不正确会有什么影响,它会杀死某人,只是惹恼他们,还是不太可能有人注意到?会容易修复吗?
您给出的方法存在风险。例如:
如果数据库非常繁忙,就有可能导致一个事务过度锁定甚至死锁,从而可能导致其他事务失败。将 TRANSACTION ISOLATION LEVEL 设置为 READ UNCOMITTED 并将 DEADLOCK PRIORITY 设置为 LOW 将有助于减少这种情况,但不能完全消除它。
其他事务可能在 READ UNCOMMITED 隔离模式下运行。在这种情况下,他们将暂时看到插入的结果,直到发出回滚。
值得注意的是,如果您正在测试的过程在其中调用 COMMIT TRANSACTION,则在调用 ROLLBACK 时可能不会得到您想要的结果。
您可能会推送数据库或日志以耗尽磁盘空间。
您可能会用完所有可用的 CPU、内存、磁盘 IO、网络或其他容量限制。
最后,我怀疑这不是一个完整的列表。我想说的是,它可能会以奇怪的方式出错。
如果您有一个完全备份的个人开发数据库,那么您甚至不需要事务,只需在事件发生后进行恢复即可。不过,这笔交易可能会为您节省一些时间。这是最安全的解决方案。
如果您使用的是共享开发数据库,您的方法可能是可以接受的,但我仍然会进行备份以防万一,特别是如果您已经与团队关系不佳。
如果您使用的是实时数据库,如果系统作为一个整体不是那么重要并且在您修复事物时可以维持一些停机时间,那么它仍然是可以接受的。再次进行备份。
如果您正在查看的数据库正在控制一个对安全至关重要的过程或其他一些关键任务功能,那么甚至不要去那里,您可能会失去对您的责任保险的无索赔或更糟的情况。在这种情况下,最好将备份恢复到测试服务器并在那里进行测试,从而创建我的第一个场景。但请注意,在执行此操作时必须考虑很多问题。例如,在测试系统中使用个人信息可能是非法的。此外,可能需要模拟其他系统的依赖项以确保您不会影响它们,例如不要将测试系统连接到实时电子邮件服务器。
如果我有一个复杂的存储过程,我希望能够测试和回滚,我添加一个输入参数(始终作为最后一个参数),@debug 默认值为 0(所以你不需要指定它当你在产品上运行)。
然后我在最后编写代码来测试参数是否 = 1,如果是,我运行任何选择查询来显示我想要查看的数据,然后使用 raiseerror 将程序发送到 catch 块(千万不要在没有尝试的情况下编写多个事务catch 块)并让它回滚。
这样您就可以轻松地在 dev 上检查结果并自动回滚。