我在sql中有一个循环,它做了一些事情
begin tran one
do some inserts in others tables
--start loop
begin tran two
--do something
begin try
--if something fail then a trigger does rollback and this return a error (and this goes to catch), then don't i need do the rollbak in catch? this could not be dissable because this is working on production
--something finished ok
commit tran two
end try
begin catch
rollback tran two
end catch
--finished loop
commit
----------
我收到了这个错误
批次结束时检测到不可提交的交易。该 交易被回滚。
begin tran one
begin tran two
rollback tran two
执行此代码我得到了这个:
无法回滚两个。找不到该名称的交易或保存点。
我只希望子查询回滚第二个循环并继续其他记录。
答案 0 :(得分:10)
操作员回滚回滚所有事务,对于仅回滚第二个循环,您必须使用保存点:
begin tran one
-- do some inserts in others tables
--start loop
save tran two -- begin tran two
--do something
begin try
update product set id = 1 --if something fail then a trigger does rollback and this return a error (and this goes to catch), then don't i need do the rollbak in catch? this could not be dissable because this is working on production
--something finished ok
commit tran two
end try
begin catch
rollback tran two
end catch
--finished loop
commit
触发示例:
create table product (id int)
GO
create trigger product_trigger on product for update
as
set xact_abort off
if (select count(*) from inserted i join product p on i.id=p.id)=0 begin
if (@@trancount>0) begin
/* rollback */
raiserror('product does not exist', 16, 1)
end
end
答案 1 :(得分:2)
就我而言,是我的代码正在通过 EF DbContext 方法(一种包含非嵌套事务的SQL Server存储过程)进行调用。
自从@NotMe已经指出“ there is no such as a nested transaction in SQL Server”以来,我开始怀疑我的过程是否真的不需要事务处理。
怀疑我的DbContext感到内,,我开始检查DbContext选项,直到 DbContext.Configuration.EnsureTransactionsForFunctionsAndCommands = True 引起了我的注意。
因此,一旦我将其值更改为 True ,一切就可以成功运行。
MyDbContext.Configuration.EnsureTransactionsForFunctionsAndCommands = false;
发生了什么事?
在我看来,EF的 ObjectContext.ExecuteFunction 方法正在管理自己的外部事务,作为存储过程内部事务的包装,因此,当我的存储过程的ROLLBACK TRAN被击中时,按下EF的COMMIT / ROLLBACK代码时,没有挂起的事务。
奇怪的是,在收集关于 EnsureTransactionsForFunctionsAndCommands 属性的一些引用时,我发现此默认行为是由于(我认为)EF团队做出的最糟糕的决定之一,因为它与每个团队都会直接冲突。 T-SQL脚本中的ROLLBACK TRAN。
有关更多详细信息,请在EF6 wraps every single stored procedure call in its own transaction. How to prevent this?上查看有洞见的SO的QA
希望它对某人有帮助:-)