2010-02-05 66 views
0

我的印象是,在将SQL Server数据库的所有更新应用到基础数据库之前,首先添加了T-Log。在服务器崩溃的情况下,恢复过程将回滚所有未提交的事务。这也是我对事务的假设,如果没有调用提交或回滚,则不会进行更改。应用于数据库的事务更新,无论是否提交或回滚

所以我想看到SQL服务器对事务被缩短的反应。即没有提交或回滚的事务更新。我发现我不太明白。特别是,SQL服务器如何允许这种情况发生。

我使用下面的脚本将行延迟插入到表中,以便让我有足够的时间在达到提交或回滚之前停止事务。我猜这将在事务完成之前模拟客户端应用程序超时。

Create Table MyTest (Comment varchar(20)) 
Go 
Create Procedure MyProc 

as 

Begin Try 
    Begin Transaction 

     Insert Into MyTest Select 'My First Entry' 

     WaitFor Delay '00:00:02' 

     Insert Into MyTest Select 'My Second Entry' 

     WaitFor Delay '00:00:02' 

     Insert Into MyTest Select 'My Third Entry' 

    Commit Transaction 

    Return 0 -- success 
End Try 

Begin Catch 
    If (@@trancount<>0) Rollback Transaction 

    Declare @err int, @err_msg varchar(max) 
    Select @err = error_number(), @err_msg = error_message() 
    Raiserror(@err_msg, 16,1) 

    Return @err 
End Catch 

如果你运行该脚本,这取决于你如何迅速停止过程中,你会看到的第一个或两个刀片将保留在表中。有人可以解释为什么会发生?

Select * From MyTest 

我测试了在SQL 2008

回答

2

正确,TXN是使用“预写日志”写入的。有关于它的MSDB文章以及它如何与提交/回滚/检查点等进行交互

但是,命令timout(或您正在执行的操作只是简单地停止代码执行)并且TXN永远不会回滚并锁定,直到连接已关闭(或稍后单独完成)。这是SET XACT_ABORT用于

1

如果你开始一个事务,不提交,或回滚它,你会简单地得到一个挂交易很可能阻止其他用户,直到事情是完成当前交易。 SQL Server不会自动提交或回滚事务,只是因为你的代码没有这样做。交易将保持原样并阻止其他用户,直到它被提交或回滚。

现在,我可以非常轻松地在我的T-SQL代码中开始一个事务,而不是提交或回滚它,然后执行Select语句并查看刚刚插入或更新的数据,只要Select语句正在使用与我的交易相同的连接。如果我尝试使用其他事务进行选择,我将看不到插入或更新的数据。事实上,直到另一个连接上的事务完成后,Select语句才可能完成。

相关问题