Ben*_*old 215
SET XACT_ABORT ON
指示SQL Server回滚整个事务并在发生运行时错误时中止批处理.它涵盖了在客户端应用程序上发生的命令超时而不是SQL Server本身(默认XACT_ABORT OFF
设置未涵盖)的情况.
由于查询超时将使事务保持打开状态,SET XACT_ABORT ON
因此建议在具有显式事务的所有存储过程中使用(除非您有特定的理由),因为应用程序在与开放事务的连接上执行工作的后果是灾难性的.
Dan Guzman博客上有一个很棒的概述,
Rem*_*anu 35
在我看来,SET XACT_ABORT ON在SQL 2k5中添加了BEGIN TRY/BEGIN CATCH已经过时了.在Transact-SQL中的异常块之前,处理错误非常困难,并且不平衡的过程非常常见(与入口相比,退出时具有不同的@@ TRANCOUNT的过程).
通过添加Transact-SQL异常处理,可以更容易地编写正确的过程,保证正确平衡事务.例如,我使用此模板进行异常处理和嵌套事务:
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
if @trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if @trancount = 0
commit;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
end catch
end
go
Run Code Online (Sandbox Code Playgroud)
它允许我编写原子过程,只有在可恢复错误的情况下回滚它们自己的工作.
Transact-SQL程序面临的主要问题之一是数据纯度:有时接收的参数或表中的数据都是完全错误的,导致重复的键错误,参考约束错误,检查约束错误等等.毕竟,这正是这些约束的作用,如果这些数据纯度错误是不可能的并且都被业务逻辑所捕获,则约束将全部过时(为效果添加了戏剧性的夸张).如果XACT_ABORT为ON,那么所有这些错误都会导致整个事务丢失,而不能正常编写处理异常的异常块.一个典型的例子是尝试执行INSERT并在PK违规时恢复为UPDATE.
Vla*_*adV 21
引用MSDN:
当SET XACT_ABORT为ON时,如果Transact-SQL语句引发运行时错误,则终止并回滚整个事务.当SET XACT_ABORT为OFF时,在某些情况下,仅回滚引发错误的Transact-SQL语句并继续处理事务.
实际上,这意味着某些语句可能会失败,使事务"部分完成",并且调用者可能没有出现此类失败的迹象.
一个简单的例子:
INSERT INTO t1 VALUES (1/0)
INSERT INTO t2 VALUES (1/1)
SELECT 'Everything is fine'
Run Code Online (Sandbox Code Playgroud)
此代码将在XACT_ABORT OFF时"成功"执行,并在XACT_ABORT为ON时终止,错误将终止("INSERT INTO t2"将不会执行,客户端应用程序将引发异常).
作为一种更灵活的方法,您可以在每个语句(旧学校)之后检查@@ ERROR,或使用TRY ... CATCH块(MSSQL2005 +).我个人更喜欢在没有理由进行某些高级错误处理时设置XACT_ABORT.
小智 6
关于客户端超时和使用XACT_ABORT来处理它们,我认为至少有一个很好的理由使客户端API(例如SqlClient)发生超时,这是为了防止客户端应用程序代码发生SQL Server代码中的死锁。在这种情况下,客户端代码没有错误,但是必须保护自己,使其永远不会阻塞,以等待命令在服务器上完成。反过来说,如果必须存在客户端超时来保护客户端代码,那么XACT_ABORT ON也必须保护服务器代码免受客户端中止的影响,以防服务器代码执行花费的时间超过客户端愿意等待的时间。
归档时间: |
|
查看次数: |
118756 次 |
最近记录: |