Задача такая.
Из клиентского приложения делаются запросы DML в одной транзакции.
Запросы могут пройти без ошибок, а может возникнуть ошибка.
Ошибки можно разделить на 2 группы:
1) Если возникла ошибка связанная, например, с обрывом соединения, либо БД инициализируется или завершается (ORA-01033: ORACLE initialization or shutdown in progress)
то можно попробовать ещё раз попробовать повторить транзакцию с теми же DML, спустя какое-то время.
2) Если возникла ошибка связанная, например, нарушением целостности внешнего ключа, то повторять те же DML смысла нет, нужны новые DML.
Вопрос: встречали ли вы где-нибудь классифицированный перечень ошибок Oracle, в котором можно выделить 2 эти группы?
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания http://rsdn.ru/Info/rules.xml
Здравствуйте, igor-booch, Вы писали:
IB>Ошибки можно разделить на 2 группы:
Нельзя. Подавляющее большинство ошибок Oracle может возникать в обеих названных ситуациях; это примерно то же самое, что по паспорту делить людей на сытых и голодных. Работоспособную схему приходится прорабатывать куда глубже.
IB>то можно попробовать ещё раз попробовать повторить транзакцию с теми же DML, спустя какое-то время.
Но если не принять специальных мер предосторожности, то такое повторение может привести к неприятным последствиям. Например, второй раз списать с абонентов месячную оплату.
IB>2) Если возникла ошибка связанная, например, нарушением целостности внешнего ключа, то повторять те же DML смысла нет,
Иногда есть. Например, если адресуемую запись должна была притащить репликация, но она по какой-то причине запаздывает.
Здравствуйте, igor-booch, Вы писали:
IB>Ошибки можно разделить на 2 группы:
IB>1) Если возникла ошибка связанная, например, с обрывом соединения, либо БД инициализируется или завершается (ORA-01033: ORACLE initialization or shutdown in progress)
Такая классификация всегда специфична для конкретной системы, общую искать бессмысленно. Ловить "с определенной целью" (ну кроме тривиальных no data found, too many rows и т.п.) нужно то, что реально может прилететь и что точно знаешь как обработать. Тут могут админы подсказать.
IB>2) Если возникла ошибка связанная, например, нарушением целостности внешнего ключа, то повторять те же DML смысла нет, нужны новые DML.
Здравствуйте, Softwarer, Вы писали:
S>Но если не принять специальных мер предосторожности, то такое повторение может привести к неприятным последствиям. Например, второй раз списать с абонентов месячную оплату.
Это как, например? Если первый раз транзакция не прошла.
Здравствуйте, wildwind, Вы писали:
W>Это как, например? Если первый раз транзакция не прошла.
Это так, когда транзакция отрабатывает на каждого абонента. И если сотня уже обработана нормально, а на сто первом случился затык, то и все на этом. Или отслеживать, что кого-то мы уже обработали. Ты же предлагаешь тупо перезапустить DML. И в этом случае с той самой первой сотни абонентов будет двойное списание, что недопустимо.
Здравствуйте, LuciferNovoros, Вы писали:
W>>Это как, например? Если первый раз транзакция не прошла.
LN>Это так, когда транзакция отрабатывает на каждого абонента. И если сотня уже обработана нормально, а на сто первом случился затык, то и все на этом. Или отслеживать, что кого-то мы уже обработали. Ты же предлагаешь тупо перезапустить DML. И в этом случае с той самой первой сотни абонентов будет двойное списание, что недопустимо.
Всегда перезапускается конкретная транзакция, а не группа, это глупо.
Тут может быть другая проблема — транзакция закоммитится, а приложение потеряет связь в момент получения этой информации и драйвер выкинет исключение. При перезапуске транзакции она исполнится два раза. Но, имхо, вероятность такого исхода почти нулевая.
Здравствуйте, Alex.Che, Вы писали:
>> Это так, когда транзакция отрабатывает на каждого абонента. AC>переведи пожалуйста. AC>(серьёзно не понял что ты хотел сказать)
Видел и неоднократно софт, который строит курсор по абонентам, а потом обрабатывает каждого в отдельной транзакции. И ситуация, когда происходят "чудеса" там весьма постоянны.
> Видел и неоднократно софт, который строит курсор по абонентам, а потом обрабатывает каждого в отдельной транзакции. > И ситуация, когда происходят "чудеса" там весьма постоянны.
Здравствуйте, Alex.Che, Вы писали:
>> >> Всегда перезапускается конкретная транзакция, а не группа
AC>и тебя сейчас не понял. AC>давайте пройдёмся по терминологии. AC>что есть в вашем понимании "конкретная транзакция", и что есть "группа" ?
Транзакция это последовательности команд от begin до commit. Группа это, если я тебя правильно понял, последовательность разных транзакций в цикле. При ошибке нужно перезапускать ту транзакцию, которая выполнялась, а не все до неё. Тогда никаких проблем быть не должно.
Здравствуйте, Alex.Che, Вы писали:
AC>а курсор в какой транзакции живёт?
В собственной. Там идет выборка на клиента, а потом с клиента дергается процедура с автономной транзакцией на борту... И не дай Б-г, если ей прилетят некорректные данные... Руки бы отрывал за такое...
Здравствуйте, Alex.Che, Вы писали:
AC>не, ребята, спорьте тут сами, без меня.
Да куда уж мы без тебя-то? Ты, как разработчик ядра СУБД, мог бы нас и просветить, ежели мы сто не так понимаем в силу ограниченности нашей.
AC>я вас обоих не понимаю.
Да тут и понимать-то нечего: есть некоторые "разработчики", которые попросту плюют на стандарты, практику и прочее. Они изобретают велосипеды с многоугольными колесами. Правда, потом сами на знают, что с ними делать, но нервы выматывают вполне качественно.