+ -
当前位置:首页 → 问答吧 → SET XACT_ABORT ON|OFF 谁能不能讲下

SET XACT_ABORT ON|OFF 谁能不能讲下

时间:2011-12-14

来源:互联网

当 SET XACT_ABORT 为 ON 时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚。

当 SET XACT_ABORT 为 OFF 时,有时只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。如果错误很严重,那么即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。OFF 是默认设置。

编译错误(如语法错误)不受 SET XACT_ABORT 的影响。



这里OFF是默认设置,换句话说一个存储过程如果开头不写SET XACT_ABORT ON 的话,这个里面如果有一句出错了,其他语句还是照样可以运行的,

那这样是不是违背了事务原理,事务不是原子性,一致性吗?,这样做还有什么意义呢?为什么默认不是ON ,因为用到事务的情况,肯定是希望事务内部语句起到 同生同灭的效果

————————————————————————
PS:我在项目中发现事务执行时报错了,但是有些数据却被更新了,才找到这个问题。



请指点迷津啊,实在想不通

作者: ruanwei1987   发布时间: 2011-12-14

谁帮我顶一下,帖子沉的太快了

作者: ruanwei1987   发布时间: 2011-12-14

SET XACT_ABORT ON时,在事务中,若出现错误,系统即默认回滚事务,但只对非自定义错误有效

SET XACT_ABORT OFF,默认值,在事务中,回滚一个语句还是整个事务视错误的严重程序而定,用户级错误一般不会回滚整个事务


备注
当 SET XACT_ABORT 为 ON 时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚。

当 SET XACT_ABORT 为 OFF 时,有时只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。如果错误很严重,那么即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。

编译错误(如语法错误)不受 SET XACT_ABORT 的影响。

对于大多数 OLE DB 提供程序(包括 SQL Server),必须将隐式或显示事务中的数据修改语句中的 XACT_ABORT 设置为 ON。唯一不需要该选项的情况是在提供程序支持嵌套事务时。有关详细信息,请参阅分布式查询和分布式事务。

SET XACT_ABORT 的设置是在执行或运行时设置,而不是在分析时设置。

示例
下列代码示例导致在含有其他 Transact-SQL 语句的事务中发生外键冲突错误。在第一个语句集中产生错误,但其他语句均成功执行且事务成功提交。在第二个语句集中,将 SET XACT_ABORT 设置为 ON。这导致语句错误使批处理终止,并使事务回滚。


USE AdventureWorks;
GO
IF OBJECT_ID(N't2', N'U') IS NOT NULL
  DROP TABLE t2;
GO
IF OBJECT_ID(N't1', N'U') IS NOT NULL
  DROP TABLE t1;
GO
CREATE TABLE t1
  (a INT NOT NULL PRIMARY KEY);
CREATE TABLE t2
  (a INT NOT NULL REFERENCES t1(a));
GO
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (3);
INSERT INTO t1 VALUES (4);
INSERT INTO t1 VALUES (6);
GO
SET XACT_ABORT OFF;
GO
BEGIN TRANSACTION;
INSERT INTO t2 VALUES (1);
INSERT INTO t2 VALUES (2); -- Foreign key error.
INSERT INTO t2 VALUES (3);
COMMIT TRANSACTION;
GO
SET XACT_ABORT ON;
GO
BEGIN TRANSACTION;
INSERT INTO t2 VALUES (4);
INSERT INTO t2 VALUES (5); -- Foreign key error.
INSERT INTO t2 VALUES (6);
COMMIT TRANSACTION;
GO
-- SELECT shows only keys 1 and 3 added. 
-- Key 2 insert failed and was rolled back, but
-- XACT_ABORT was OFF and rest of transaction
-- succeeded.
-- Key 5 insert error with XACT_ABORT ON caused
-- all of the second transaction to roll back.
SELECT *
  FROM t2;
GO



语法

 
SET NOCOUNT { ON | OFF }
 

备注
当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数)。当 SET NOCOUNT 为 OFF 时,返回计数。

即使当 SET NOCOUNT 为 ON 时,也更新 @@ROWCOUNT 函数。

当 SET NOCOUNT 为 ON 时,将不向客户端发送存储过程中每个语句的 DONE_IN_PROC 消息。使用由 SQL Server 2005 提供的实用工具执行查询时,其结果会防止在 Transact-SQL 语句(例如 SELECT、INSERT、UPDATE 和 DELETE)的末尾显示 nn rows affected。

如果存储过程中包含的一些语句并不返回许多实际数据,则该设置由于大量减少了网络流量,因此可显著提高性能。

SET NOCOUNT 设置是在执行或运行时设置,而不是在分析时设置。

权限
要求具有 public 角色的成员身份。

示例
以下示例将禁止显示受影响的行数的消息。 


USE AdventureWorks;
GO
SET NOCOUNT OFF;
GO
-- Display the count message.
SELECT TOP(5)LastName
FROM Person.Contact
WHERE LastName LIKE 'A%';
GO
-- SET NOCOUNT to ON to no longer display the count message.
SET NOCOUNT ON;
GO
SELECT TOP(5) LastName
FROM Person.Contact
WHERE LastName LIKE 'A%';
GO
-- Reset SET NOCOUNT to OFF
SET NOCOUNT OFF;
GO


作者: hefeng_aspnet   发布时间: 2011-12-14

引用楼主 ruanwei1987 的回复:
▪ 网格计算、高性能计算、并行计...▪ 如何在云中管理非结构化数据?▪ 酒店行业的CIO们是如何看待云计...▪ 向私有云过渡的步骤有哪些?▪ 什么叫做云打印?如何建立云打...当 SET XACT_ABORT 为 ON 时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚。

当 SET XACT_ABORT 为 OFF 时,有时只回滚产生错误的 Transa……

需要在存储过程中显示的开启事务的

begin tran

comit tran

rollback tran

作者: Sandy945   发布时间: 2011-12-14

存储过程不具备事务的特性,但是可以在它内部使用事务

http://bbs.bitscn.com/243655

作者: Sandy945   发布时间: 2011-12-14

引用 2 楼 hefeng_aspnet 的回复:
SET XACT_ABORT ON时,在事务中,若出现错误,系统即默认回滚事务,但只对非自定义错误有效

SET XACT_ABORT OFF,默认值,在事务中,回滚一个语句还是整个事务视错误的严重程序而定,用户级错误一般不会回滚整个事务


备注
当 SET XACT_ABORT 为 ON 时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚。

当……
是这样的

作者: ssp2009   发布时间: 2011-12-14

菜鸟程序员 、阿非、今生为你还

begin tran

comit tran

rollback tran

存储过程默认情况下,在上面这个语句中不会 回滚的,

加上 SET XACT_ABORT ON 才会回滚


我想知道 为什么Sql Server采用这样的方式,默认回滚不行吗?

作者: ruanwei1987   发布时间: 2011-12-14

SQL code

create table testTb
  (
     Name varchar(20) unique
  )
  
  create proc up_customProc
  as
  insert into testTb values('1')
  insert into testTb values('1')
  
  select * from testTb
  exec up_customProc
    select * from testTb
    delete from  testTb
    
  create proc up_customProc1
  as
  begin tran
  insert into testTb values('2')
  insert into testTb values('2') 
  if @@ERROR=0
      commit tran
  else
      rollback tran 
      select * from testTb
  exec up_customProc1
    select * from testTb

作者: Sandy945   发布时间: 2011-12-14

阿非,
我知道你这样的意思,
up_customProc 添加进了1条数据,
up_customProc1 却一条也添加不进去,因为出错了
但是我把你第二个存储过程稍微改了一下:
 create proc up_customProc1
  as
  begin tran
  insert into testTb values('2')
  insert into testTb values('2') 
  SELECT 1
  if @@ERROR=0
  commit tran
  else
  rollback tran 



我在里面添加了一条 select 1这样的情况 数据反倒加进去了,

作者: ruanwei1987   发布时间: 2011-12-14

SQL code

  create table testTb
  (
     Name varchar(20) unique
  )
  
  create proc up_customProc
  as
  insert into testTb values('1')
  insert into testTb values('1')
  
  select * from testTb
  exec up_customProc
    select * from testTb
    delete from  testTb
    
  create proc up_customProc1
  as
  begin try
    begin tran
        insert into testTb values('2')
        insert into testTb values('2') 
        select 1
    commit tran
  end try
  begin catch
     rollback
  end catch

      select * from testTb
  exec up_customProc1
    select * from testTb

作者: Sandy945   发布时间: 2011-12-14