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

在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

-- 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;