Sql 无法回滚子事务。找不到该名称的事务或保存点
在sql中,我有一个循环,它做一些与之类似的事情Sql 无法回滚子事务。找不到该名称的事务或保存点,sql,tsql,loops,transactions,Sql,Tsql,Loops,Transactions,在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
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
-- 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
在我的例子中,我的代码是否通过EF DbContext方法调用SQL Server存储过程,该存储过程包含一个非嵌套事务 因为,@NotMe已经指出,我开始怀疑我的流程是否真的是无事务嵌套的 我怀疑我的DbContext有些内疚,于是开始检查DbContext选项,直到DbContext.Configuration.EnsureTransactionsForFunctionsAndCommands=True引起我的注意 所以,当我把它的值改为True时,一切都成功了
MyDbContext.Configuration.EnsureTransactionsForFunctionsAndCommands = false;
发生了什么事
在我看来,EF的ObjectContext.ExecuteFunction方法将其自己的外部事务作为存储过程内部事务的包装进行管理,因此,当我的存储过程的回滚事务被命中时,当EF的提交/回滚代码被命中时,没有挂起的事务
奇怪的是,在收集有关EnsureTransactionsForFunctionsAndCommands属性的一些引用时,我发现这种默认行为是由于EF团队有史以来最糟糕的决定之一,因为它与T-SQL脚本中的每个回滚传输直接冲突
有关更多详细信息,请访问insightfull SO的QA
希望它能帮助别人:-回顾这个问题:请特别注意顶部答案中的链接。本质上,SQL server中没有嵌套事务。如果我可以重命名第一个事务,这是可以的,但正如我所说,有一个触发器会回滚,那么我无法修改它,因为这是在生产中,这只会回滚,如果这只会回滚一个,这可能会起作用,但这只会回滚,那么这段代码就不起作用了。如果从插入的i中选择count*,i.id=p.id=0开始如果@@trancount>0开始回滚raiseerror“产品不存在”结束结束我添加了一个触发器示例直到找到这个答案之前,我一直在寻找错误的方向。非常感谢。
MyDbContext.Configuration.EnsureTransactionsForFunctionsAndCommands = false;