我工作的公司专门为所有数据库交互、选择、更新、删除使用存储过程(和一个本地的ORM)。
我们有许多procs将从表中插入和/或更新和/或删除。
当需要对整个proc进行“事务化”时,显然需要有我们的commit和rollback语句。
问题从何而来。
当一个事务中有多个语句需要一起提交或回滚时,我们显然会抛出一个try/catch块。
让我们假设脚本的这个示例场景:
set nocount on
create table #test
(
id int primary key identity(1,1),
col varchar(2) not null,
y int not null
)
begin tran
begin try
insert into #test ( col, y ) values ('GA', 4)
update #test set col = 'DO', y = y / 0
insert into #test ( col, y ) values ('aa', 7)
commit
end try
begin catch
select error_message()
rollback
end catch
select * from #test t
drop table #test现在,这就是我写脚本的方式。
让我们假设update语句(第2条语句)会导致异常。然后将焦点移到catch块,从而执行rollback命令,取消在insert中完成的所有工作。
他们说,为了使rollback真正回滚所有语句,而不是导致异常的语句,编写如下脚本:
set nocount on
set xact_abort on ------------------------------------------------
create table #test
(
id int primary key identity(1,1),
col varchar(2) not null,
y int not null
)
begin tran
begin try
insert into #test ( col, y ) values ('GA', 4)
update #test set col = 'DO', y = y / 0
insert into #test ( col, y ) values ('aa', 7)
commit
end try
begin catch
select error_message()
if (xact_state() <> 0) -------------------------------------------------
rollback
end catch
select * from #test t
drop table #test现在,当我测试这两个示例时,它们都得到了相同的预期结果(表中没有记录)。
如果只在try/catch中包装多个语句就可以完成相同的任务(在出现异常时回滚多个语句),那么执行xact_abort和xact_state操作有什么意义呢?
发布于 2016-10-25 15:25:40
这在dba.stackexchange.com上会更好
夏克特_状态()不影响回滚的行为。是关于国家的。
1当前请求具有一个活动用户事务。请求可以执行任何操作,包括写入数据和提交事务。 0当前request. -1没有活动用户事务-1当前请求有一个活动用户事务,但是发生了一个错误,导致事务被归类为不可提交的事务。请求不能提交事务或回滚到保存点;它只能请求事务的完整回滚。在回滚事务之前,请求不能执行任何写操作。请求只能执行读操作,直到它回滚事务。事务回滚后,请求可以同时执行读和写操作,并可以开始一个新事务。
指定当Transact-SQL语句引发运行时错误时,Server是否自动回滚当前事务。
你得试一试。错误/异常将导致捕获,捕获将调用回滚。XACT_ABORT不影响显式回滚。
请参阅链接中的示例。第二个应该回滚,即使没有尝试捕获。
在第一种情况下,我打赌即使设置了xact_abort,它也会全部回滚。
https://softwareengineering.stackexchange.com/questions/330047
复制相似问题