我正在通过C#应用程序对数据库执行存储过程。我想在执行存储过程后进行计算,然后在计算完成后,我想将数据库回滚到存储过程之前的状态。我在堆栈溢出时看到的大多数示例只涉及在发生错误时在try / catch块的catch块中使用回滚,但这与我正在做的不同。
我不确定是否应该在某个时刻保存数据库的状态,然后使用该状态执行事务回滚,或者应该将事务参数附加到SqlCommand
实例的存储过程,或其他。
答案 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
回滚事务不会影响表变量中的内容。我相信这不仅仅是指望我的应用程序回滚事务。并不是说它不会起作用,但我只相信这一点。
话虽这么说,你可以创建一个SqlTransaction
(docs),使用该事务执行你的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