首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么CATCH块允许在Server 2012中提交事务

为什么CATCH块允许在Server 2012中提交事务
EN

Stack Overflow用户
提问于 2016-06-03 15:01:59
回答 1查看 1.1K关注 0票数 4

最近,由于遗留代码中的以下语句,我遇到了一个SQL错误。它尝试删除一个临时表,如果还没有定义它,就继续前进。显然,检查临时表的存在不是一个好方法,但这不是我的问题。

代码语言:javascript
复制
BEGIN TRY 
    DROP TABLE #my_temp_table
END TRY 
BEGIN CATCH 

END CATCH 

该语句运行良好(没有任何错误),但是一旦您像下面这样将其放入一个Begin /Commit Tran块中,行为就会变得有趣起来。

代码语言:javascript
复制
BEGIN TRAN
    BEGIN TRY 
        DROP TABLE #my_temp_table
    END TRY 
    BEGIN CATCH 

    END CATCH 
COMMIT TRAN

我的理解是,Try..Catch块不影响事务--一旦进入Catch块,事务将处于不可提交状态,事务将被回滚,这就是我在Server 2008 R2 (SP1)上看到的- 10.50.2550.0。当它在Begin Tran/Commit Tran块中执行时,我们将得到一个错误:

代码语言:javascript
复制
Msg 3930, Level 16, State 1, Line 8
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
Msg 3998, Level 16, State 1, Line 1
Uncommittable transaction is detected at the end of the batch. The transaction is rolled back.

但是,它在SQLServer2012-11.0.5058.0上运行时没有任何错误。XACT_STATE()在结束捕获行后返回1。事务将被提交,如果在DROP语句之前和之后有其他数据更改,则更改将保持不变。

代码语言:javascript
复制
BEGIN TRAN
    BEGIN TRY 
        DROP TABLE #my_temp_table
    END TRY 
    BEGIN CATCH 

    END CATCH 
    PRINT XACT_STATE()
COMMIT TRAN

在所有这些测试中,我确保XACT_ABORT已关闭。所以我的问题是什么会导致这种行为差异。这是2008年R2和2012年的不同之处,还是一些服务器/DB设置控制了Try...Catch块和事务的工作方式。

编辑1:我尝试在2008年R2和2012年实例上运行以下脚本。我还尝试将INSERT dbo.UserOptionsLog行放在不同的位置,在开始尝试之前,在开始尝试之后,在开始捕获之后,在提交Tran之后,但是它不会改变结果。

代码语言:javascript
复制
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'UserOptionsLog')
    CREATE TABLE dbo.UserOptionsLog([Set Option] SYSNAME, [Value] VARCHAR(100), ID INT IDENTITY NOT NULL)


BEGIN TRAN
    DELETE FROM dbo.UserOptionsLog
    INSERT dbo.UserOptionsLog EXEC('DBCC USEROPTIONS')
    SELECT * FROM dbo.UserOptionsLog

    BEGIN TRY 

        DROP TABLE #my_temp_table
    END TRY 
    BEGIN CATCH 

    END CATCH 
COMMIT TRAN

2008年R2实例的结果。

代码语言:javascript
复制
Set Option  Value   ID
textsize    2147483647  40
language    us_english  41
dateformat  mdy 42
datefirst   7   43
lock_timeout    -1  44
quoted_identifier   SET 45
arithabort  SET 46
ansi_null_dflt_on   SET 47
ansi_warnings   SET 48
ansi_padding    SET 49
ansi_nulls  SET 50
concat_null_yields_null SET 51
isolation level read committed  52

来自2008年R2实例的消息

代码语言:javascript
复制
(0 row(s) affected)
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

(13 row(s) affected)

(13 row(s) affected)
Msg 3930, Level 16, State 1, Line 18
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
Msg 3998, Level 16, State 1, Line 1
Uncommittable transaction is detected at the end of the batch. The transaction is rolled back.

2012年的结果。

代码语言:javascript
复制
Set Option  Value   ID
textsize    2147483647  53
language    us_english  54
dateformat  mdy 55
datefirst   7   56
lock_timeout    -1  57
quoted_identifier   SET 58
arithabort  SET 59
ansi_null_dflt_on   SET 60
ansi_warnings   SET 61
ansi_padding    SET 62
ansi_nulls  SET 63
concat_null_yields_null SET 64
isolation level read committed  65

来自2012年实例的信息。

代码语言:javascript
复制
(13 row(s) affected)
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

(13 row(s) affected)

(13 row(s) affected)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-03 15:21:42

...and,这就是我在Server 2008 R2 (SP1)上看到的- 10.50.2550.0。当它在Begin Tran/Commit Tran块中执行时,我们将得到一个错误: Msg 3930,级别16,状态1,第8行当前事务无法提交,也不能支持写入日志文件的操作。回退交易。在批处理结束时检测到Msg 3998、级别16、状态1、第1行不可提交事务。事务被回滚。但是,它在SQLServer2012-11.0.5058.0上运行时没有任何错误。..。

我相信这种差异的原因。行为是XACT_ABORT设置的值。

OFF然后XACT_STATE()返回1时,TX是可提交的,而COMMIT TRAN执行时没有错误:

代码语言:javascript
复制
SET XACT_ABORT OFF
BEGIN TRAN
    BEGIN TRY 
        DROP TABLE #my_temp_table
    END TRY 
    BEGIN CATCH 

    END CATCH 
    PRINT XACT_STATE()
COMMIT TRAN

但是ON是什么时候?

代码语言:javascript
复制
SET XACT_ABORT ON
BEGIN TRAN
    BEGIN TRY 
        DROP TABLE #my_temp_table
    END TRY 
    BEGIN CATCH 

    END CATCH 
    PRINT XACT_STATE()
COMMIT TRAN

由于CATCH块截获了错误/异常,TX变为圆顶/不可提交(-1),COMMIT TRAN引发另一个错误/异常:

代码语言:javascript
复制
-1
Msg 3930, Level 16, State 1, Line 10
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.

更新:

我在SQL2008R2上复制了报道的行为。在2008R2上,似乎无论什么值有XACT_ABORT ( On /OFF),TX都会变得不确定。SQL2012因此改变了这种行为:只有当XACT_ABORT打开时,TX才会变得无法提交。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37617704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档