如何执行存储过程,然后稍后回滚更改?

时间:2016-07-01 18:26:54

标签: c# sql-server tsql stored-procedures rollback

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

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

4 个答案:

答案 0 :(得分:0)

您可以通过交易完成此操作。示例在这里:https://msdn.microsoft.com/en-us/library/86773566(v=vs.110).aspx是的,它也使用了catch块,但您不必使用。

或者,如果您的SQL Server版本支持数据库快照,则可以使用数据库快照,但是它们将回滚所有变更,因为我们和您的任何其他用户一起制作了快照。很可能这不是你想要的。

答案 1 :(得分:0)

一种选择是将WAITFOR DELAY与修改后的事务隔离级别结合使用。这样做是执行代码,使查询等待一段时间,然后回滚事务。在您指定的那段时间内,您可以从接收修改的表中获得另一个会话查询(只要您将事务级别设置为未提交读取),您就可以看到新值。这是一个示例:

在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分钟内,您将在临时表中看到值。一分钟后,表格将为空白。这适用于稍微简单的任务,但是如果您正在对已经对其进行测试更改的数据进行测试,则只需执行快照或数据库还原。

答案 2 :(得分:0)

标准免责声明:这可能不是一件好事。 (好的,已经完成了。)

您可以使用table variable在存储过程中最轻松地完成此操作。你可以

开始交易 修改你的数据
查询修改后的数据
将其插入表变量
回滚交易
选择表变量

中的内容
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

回滚事务不会影响表变量中的内容。我相信这不仅仅是指望我的应用程序回滚事务。并不是说它不会起作用,但我只相信这一点。

话虽这么说,你可以创建一个SqlTransactiondocs),使用该事务执行你的SqlCommand,查询你的数据,然后回滚事务。

答案 3 :(得分:0)

在ORACLE数据库上,如果要在PL / SQL程序中等待(“睡眠”),则可能要使用软件包“ DBMS_LOCK”中的过程“ SLEEP”。

CREATE PROCEDURE execution(xVal NUMBER) IS
      BEGIN

          INSERT INTO TABLE_1 VALUES (xVal);

          DBMS_LOCK.Sleep (60);
          ROLLBACK;
       END execution