Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Oracle > Транзакции через серию запросов


Автор: Keeper89 17.1.2011, 23:21
Доброго времени суток.

Имеется функция Delphi для выполнения простых запросов (Execute).
Как используя только ее, можно реализовать механизм транзакция в виде:
Код

НАЧАЛО ТРАНЗАКЦИИ
Команда 1
Команда 2
...
Команда N
КОНЕЦ ТРАНЗАКЦИИ

При этом необходимо предусмотреть откат всех операций в случае ошибки.

Заранее спасибо за предложенные идеи/варианты.

Автор: Zloxa 17.1.2011, 23:59
не завершать транзакцию внутри функции Delphi для выполнения простых запросов (Execute) и откатывать транзакцию в случае возникновения ошибки.

Автор: Keeper89 18.1.2011, 00:39
Zloxa, пока имеется вот такой фрагмент:
Код

Result := ExecSQL('SAVEPOINT ' + s);
   try
     for i := 0 to ASQLList.Count - 1 do
     begin
       if Trim(ASQLList[i]) = '' then
         Continue;
       Result := ExecSQL(ASQLList[i]);
       if not Result then
         Break;
     end;
    except
      ExecSQL('ROLLBACK TO SAVEPOINT ' + s);
      raise
    end;

   if Result then
     Result := ExecSQL('COMMIT'
   else
     Result := ExecSQL('ROLLBACK TO SAVEPOINT' + s)

Автор: Zloxa 18.1.2011, 08:33
Цитата(Keeper89 @  18.1.2011,  00:39 Найти цитируемый пост)
пока имеется вот такой фрагмент

о чем мне этот фрагмент, с Вашей точки зрения, должен рассказать?

Автор: Zloxa 18.1.2011, 08:51
Зачем откат вы производите на сейвпоинт? Почему не просто rollback?

Автор: Keeper89 18.1.2011, 10:45
чтобы откатиться и определенному моменту, или я неправильно понимаю? 

Автор: Zloxa 18.1.2011, 11:43
Keeper89, а коммитите вы тоже определенный момент?

Просто не однозначно какт-то. В случае успеха вы коммитите всю транзакцию, в случае ошибки - откатываете только ее часть. Обычно так не делают.

Откат к сейвпоинту обычно применяют в процедурах, не управляющих транзакцией - не начинающих ее и не завершающих. Предполагается, что управление транзакциясми в этом случае производится уровнем выше. Если же ваша процедура таки управляет транзакцией, то откатывайте ее уж полностью.

Автор: Keeper89 18.1.2011, 22:52
Цитата(Zloxa @  18.1.2011,  11:43 Найти цитируемый пост)
Просто не однозначно как-то. В случае успеха вы коммитите всю транзакцию, в случае ошибки - откатываете только ее часть. Обычно так не делают.

Нет, коммит подразумевается только для того, что сделано с сейвпоинта. Может я синтаксически неверно это оформил?

Переделал следующим образом (на ХП):
Код

BEGIN
    SAVEPOINT %1;
    {СПИСОК ЗАПРОСОВ}
    COMMIT;
    EXCEPTION
        WHEN OTHERS
            THEN ROLLBACK TO SAVEPOINT %1;
END;

Так более грамотно, или лучше вообще убрать сейвпоинт и просто делать ROLLBACK?

Автор: Zloxa 18.1.2011, 23:50
Цитата(Keeper89 @  18.1.2011,  22:52 Найти цитируемый пост)
коммит подразумевается только для того, что сделано с сейвпоинта

так не бывает.
Коммит зафиксирует все что было понаделано и до сейвпоинта(если  было).
Именно поэтому роллбак к сейвпоинту рядом с коммитом выглядит несколько... неорганично.

Автор: Keeper89 19.1.2011, 00:28
Zloxa, а как лучше записать тогда, чтобы применять/откатывать только часть инструкций?

Добавлено через 4 минуты и 10 секунд
Цитата(Keeper89 @  18.1.2011,  22:52 Найти цитируемый пост)
Так более грамотно, или лучше вообще убрать сейвпоинт и просто делать ROLLBACK? 


Автор: Zloxa 19.1.2011, 09:57
Keeper89, сколько мне еще раз повторить что коммит "части инструкций" не бывает? Сколько мне еще раз повторить, что там где используется коммит, уместен роллбек, а не ролбек к сейвпоинту?

Автор: Keeper89 20.1.2011, 01:38
Цитата(Zloxa @  19.1.2011,  09:57 Найти цитируемый пост)
Keeper89, сколько мне еще раз повторить что коммит "части инструкций" не бывает? Сколько мне еще раз повторить, что там где используется коммит, уместен роллбек, а не ролбек к сейвпоинту? 

Т.е. http://www.java2s.com/Code/Oracle/Table/Rollbacktosavepointinexceptionhandler.htm имеется ошибка?
Код

BEGIN
    {СПИСОК ЗАПРОСОВ}
    COMMIT;
    EXCEPTION
        WHEN OTHERS
            THEN ROLLBACK;
END;

Так правильно?

И если 
Цитата(Zloxa @  19.1.2011,  09:57 Найти цитируемый пост)
коммит "части инструкций" не бывает

как можно разобраться с моей проблемой?

Автор: Zloxa 20.1.2011, 09:46
Цитата(Keeper89 @  20.1.2011,  01:38 Найти цитируемый пост)
Т.е. здесь имеется ошибка?

Где Вы там узрели фиксацию транзакции?
Цитата(Keeper89 @  20.1.2011,  01:38 Найти цитируемый пост)
Так правильно?

так - разумно.
правильно было и раньше.
одна оговорка, эксепшн чтоб не терять
Код

BEGIN
    {СПИСОК ЗАПРОСОВ}
    COMMIT;
    EXCEPTION
        WHEN OTHERS
            THEN ROLLBACK;raise;
END;

Цитата(Keeper89 @  20.1.2011,  01:38 Найти цитируемый пост)
как можно разобраться с моей проблемой?

Наверняка - можно, просто Я не понимаю в чем Ваша проблема и о чем мы тут в этом топике дискутируем.
Сдается мне, Вам просто вскучнулось и Вы решили уныло пообсуждать банальные вещи.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)