如何执行存储过程,然后在以后回滚更改

本文关键字:然后 何执行 执行 存储过程 | 更新日期: 2023-09-27 17:54:06

我正在通过c#应用程序对数据库执行一个存储过程。我希望在存储过程执行之后进行计算,然后在计算完成之后,我希望将数据库回滚到存储过程之前的状态。我看到的大多数关于堆栈溢出的例子只涉及在发生错误时在try/catch块的catch块中使用回滚,但这与我所做的不同。

我不确定我是否应该在某个时刻保存数据库的状态,然后使用该状态执行事务回滚,或者应该将事务参数附加到存储过程的SqlCommand实例,或者其他东西。

如何执行存储过程,然后在以后回滚更改

您可以通过事务来实现这一点。示例在这里:https://msdn.microsoft.com/en-us/library/86773566(v=vs.110).aspx是的,它也使用catch块,但你不必。

或者你可以使用数据库快照,如果你的版本的SQL Server支持他们,但他们会回滚所有的更改,因为快照的时刻,你和任何其他用户。这很可能不是你想要的。

一种选择是将WAITFOR DELAY与修改后的事务隔离级别结合使用。它的作用是执行代码,使查询等待一段时间,然后回滚事务。在指定的时间内,您可以从收到修改的表中进行另一个会话查询(只要将事务级别设置为read uncommitted),并且您将能够看到新值。下面是一个示例:

在SSMS的一个窗口中:

CREATE TABLE ##testtable (id INT);
BEGIN TRAN;
INSERT INTO ##testtable (id)
VALUES (1), (2), (3);
WAITFOR DELAY '00:01:00';
ROLLBACK TRAN

在第二个SSMS窗口中,在1分钟的时间范围内运行此查询:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
SELECT * 
FROM ##testtable 

在另一个窗口正在执行的1分钟内,您将看到临时表中的值。一分钟后,桌子将是空白的。这适用于一些简单的任务,但是如果您正在对已经有测试更改的数据进行测试,则只需执行快照或数据库恢复。

标准免责声明:这可能不是一件好事。(好了,就这样了。)

在存储过程中使用表变量最容易做到这一点。你可以

开始事务
修改数据
查询修改数据
将其插入表变量
回滚事务
选择表变量

中的内容
declare @myData table (someColumn int, someOtherColumn varchar(10))
begin transaction
begin try   
    [make your changes]
    insert into @myData
    select something, something something
    rollback transaction
    select * from @myData
end try
begin catch
    rollback transaction
end catch

回滚事务不会影响table变量中的内容。比起指望我的应用程序回滚事务,我更相信这一点。不是说它行不通,而是我更相信它。

也就是说,您可以创建一个SqlTransaction (docs),使用该事务执行SqlCommand,查询数据,然后回滚该事务。

在ORACLE数据库中,如果你想在PL/SQL程序中等待(" sleep "),你可能想使用" DBMS_LOCK "包中的" sleep "过程。

CREATE PROCEDURE execution(xVal NUMBER) IS
      BEGIN
          INSERT INTO TABLE_1 VALUES (xVal);
          DBMS_LOCK.Sleep (60);
          ROLLBACK;
       END execution