MSSQL2008,运行2段代码:
运行1:
create table a (x char(10),y int)
go
create trigger [dbo].[a_limit] on [dbo].[a]
for insert
as
if exists(select 1 from inserted where y>0)
raiserror('错误',16,1)
go
set xact_abort on
begin tran
insert into a values('001',1)
insert into a values('002',2)
commit tran
go
--------结果---------
x y
001 1
002 2
运行2:
create table a (x char(10),y int)
go
create trigger [dbo].[a_limit] on [dbo].[a]
instead of insert
as
if exists(select 1 from inserted where y>1)
raiserror('错误',16,1)
go
set xact_abort on
insert into a values('001',1)
insert into a values('002',2)
go
--------结果---------
x y
问题1:set xact_abort on是否一定要跟begin tran/***/commit tran才能回滚?
问题2:运行1的表a加了for触发器,插入操作加了事务,2句插入语句都抛出错误,为什么事务没有回滚?
问题3:运行2的表a加了instead of触发器,插入操作没有加事务,第2句插入语句抛出错误,为什么第1条插入语句也回滚了?
问题4:set xact_abort on/begin tran/***/commit tran和begin tran/try***/catch***/commit tran有什么区别?
------解决方案--------------------
问题1:是的,xact_abor只是个选项,要配合显示事务才有效果
问题2:你定义的错误只能被try catch捕获处理,不能引发tran的回滚,就如你定义的只是个提示,并没有真正意义上事务的错误
问题3:如2所说,其实并没有引发回滚,而是你定义的instead of触发器代替了insert操作,只给出了一个提示
问题4:加上try catch的话就可以处理你定义的那种错误提示了,可以转到catch语句块中进行显示rollback操作
------解决方案--------------------
请不要误导
create table a (x char(3),y int)
set xact_abort on
insert into a values('001',1)
insert into a values('0032',2)
insert into a values('003',3)
set xact_abort off
go
select * from a
/*
(1 行受影响)
消息 8152,级别 16,状态 14,第 11 行
将截断字符串或二进制数据。
(1 行受影响)
x y
001 1
*/
set xact_abort on
begin tran
insert into a values('001',1)
insert into a values('0032',2)
insert into a values('003',3)
commit
set xact_abort off
go
select * from a
(1 行受影响)
消息 8152,级别 16,状态 14,第 12 行
将截断字符串或二进制数据。
(0 行受影响)
x y
----------
------解决方案--------------------
额,弄错了,,抱歉,这个试开启隐式回滚
而非隐式事务,谢谢的szm341,看来我对set xact_abort on的理解看来有严重错误,多谢指导。
具体范例MSDN上有详细例子
而你的问题回答就应该这样
问题1:set xact_abort on是否一定要跟begin tran/***/commit tran才能回滚?
begin tran。。 commit tran是显示开启事务,若不开启,将只会回滚出错的那条语句