无论是否提交或回滚,都应用于数据库的事务更新

时间:2010-02-05 10:47:12

标签: sql-server-2008 transactions

我的印象是,在应用于底层数据库之前,首先将SQL服务器数据库的所有更新添加到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 个答案:

答案 0 :(得分:2)

正确,TXN使用“Write Ahead Logging”写入。有关于它的MSDB文章以及它如何与提交/回滚/检查点等交互

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

答案 1 :(得分:1)

如果您开始交易并且不提交或回滚,您只需获得一个挂起的交易,该交易可能会阻止其他用户,直到当前交易完成。 SQL Server不会自动提交或回滚事务,只是因为您的代码没有这样做。该事务将保留在原位并阻止其他用户,直到它被提交或回滚为止。

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