Откатить подоперации. Транзакция или точка сохранения этого имени не найдены

у меня есть цикл в 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

делает этот код, я получаю это:

откатить два. Транзакция или точка сохранения этого имени не найдены.

Я только хочу, чтобы подзапрос откатил второй цикл и продолжайте с другими записями.

2 ответов


оператор отката откатывает все транзакции, для отката только второго цикла вы должны использовать savepoints:

  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 уже указал, что"в SQL Server нет таких вложенных транзакций, как", я задался вопросом, является ли мой процесс был действительно сделка-nestingless.

подозревая, что мой DbContext имел некоторую вину, я начал проверять параметры DbContext, пока DbContext.Конфигурация.EnsureTransactionsForFunctionsAndcommands = True привлекло мое внимание.

Так вот, как только я изменил его значение True, все хорошо работает.

MyDbContext.Configuration.EnsureTransactionsForFunctionsAndCommands = false;

Что случилось?

ну, на мой взгляд, EF ObjectContext.ExecuteFunction метод управлял собственной внешней транзакцией как оболочкой внутренней транзакции моей хранимой процедуры, поэтому, когда откат моей хранимой процедуры TRAN был поражен, не было ожидающей транзакции, когда код фиксации/отката EF был поражен.

Как ни странно, собирая некоторые ссылки на EnsureTransactionsForFunctionsAndcommands свойство, я обнаружил, что это поведение по умолчанию связано с одним из худших (на мой взгляд) решений команды EF, поскольку оно сталкивается с каждым откатом TRAN внутри скрипта T-SQL.

для получения дополнительной информации проверьте insightfull SO'S QA at EF6 оборачивает каждый хранимая процедура вызывает собственную транзакцию. Как это предотвратить?

надеюсь, это поможет кому-то: -)