Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
Господа, я понимаю, конечно, что я лопух и чего-то не догоняю, но именно поэтому я и задаю здесь свой вопрос. А вопрос заключается вот в чём. Насколько я понимаю, сермяжная суть механизма транзакций заключается в том, что набор действий (выборка данных, изменения в таблицах и т.д.), ограничиваемый транзакцией, либо выполняется ВЕСЬ , либо не выполняется ВООБЩЕ . Для меня это было интуитивно очевидно, пока я не столкнулся со следующей ситуацией, поясню её на примере: create table test ( Value integer not NULL, ) begin transaction insert into test (Value) values (NULL) insert into test (Value) values (1) commit transaction select * from test Здесь специально представлена ошибочная ситуация в первой инструкции "insert" со вставкой NULL значения в столбец, который не допускает NULL-ов. Таким образом, логично было бы, что раз первая операция прошла неудачно, то по завершению транзакции (а ключевое слово "commit" я понимаю как попытку удачно завершить транзакцию, если это возможно) вторая операция сама собой должна бы отмениться. Но не тут то было, запуск этого примера в QA на Microsoft SQL Server 7.0, как ни в чём не бывало, выдаёт таблицу с одним вставленным рядом, тем самым сводя на нет суть механизма транзакций. Ну да ладно, думаю я, раз так, буду в конце транзакции проверять состояние и, если произошла ошибка, делать принудительный "rollback". Но, порывшись в доступных мне источниках, я не нашёл, как узнать состояние системы, происходили ли ошибки в транзакции и насколько серьёзные (я имею ввиду инструкцию "raiserror" и её параметр "severity level"). Порывшись в системных процедурах, в надежде узнать от самих титанов мирового программирования, как же разрешать подобные ситуации, я обнаружил, что они используют проверку (@@error<>0), что с моей точки зрения не является решением, ведь эта системная переменная содержит код ошибки только самой последней операции, а если у меня сложный запрос? А если ошибка происходит во вложенной процедуре? И потом, это что ж, мне надо будет вписывать "if @@error<>0 goto fail" после каждой маломальски серьёзной инструкции? В общем, я в полной прострации и буду находиться в ней, пока кто-нибудь не подскажет мне, как мне бороться с этой ситуацией и чего я здесь, лопух, не догоняю. А ведь мне позарез надо написать довольно ответственную базу данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2001, 12:11 |
|
||
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
2 Serge Были уже здесь ветки на эту тему, Если Вы хотите откатить транзакцию, то должны сами проверить ошибки откатить ее оператором rollback transaction. В принципе существует возможность автоматического отката трнзакций см. в BOL SET XACT_ABORT только испульзуя эту установку нужно помнить, что она действует только если возникают run time ошибки. Т. е. если нужно откатить транзакцию основываясь на бизнес правилах все равно нужно использовать rollback. >а если у меня сложный запрос? А если у вас сложная транзакция, состоящая из нескольких запросов можно делать например так: declare @vError int begin tran update YourTable set..... set @vError = @@error insert YourTable.... set @vError = @vError + @@error if @vError <> 0 rollback tran commit tran ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2001, 12:29 |
|
||
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
2 Genady Да, Геннадий, посмотрел я на работу опции SET XACT_ABORT ON и стало мне ещё тоскливей. А именно, пишу (с включённым режимом XACT_ABORT): ... -- Что-то там такое begin transaction insert into test (Value) values (NULL) insert into test (Value) values (1) commit transaction insert into test (Value) values (2) ... -- Что-то там этакое И получаю в результате следующее. Инструкции до "begin transaction" выполняются и остаются, это нормально. Но вот после сбойной команды "insert" происходит не только откат до начала транзакции, но и прекращение выполнения процедуры вообще, т.е. инструкции следующие за "commit transaction" не выполняются вообще, хотя в режиме "XACT_ABORT OFF" они бы выполнились Таким образом, получается всё ж таки, что проблема не решена. Мне ведь не надо прерывать выполнение процедуры, мне всего лишь надо откатить неудачную транзакцию и при этом гарантировать, что я отлавливаю все возможные ошибки в процессе транзакции, как явные так и скрытые. Как я уже понял (о чём я написал ранее), конечно существует решение, связанное с проверкой на ошибки после каждой инструкции, но, как я там же отметил, это решение мне всё же не нравится по ряду причин. Самое замечательное было бы, если можно было бы контролировать, вызывались ли инструкции raiserror и с каким severity level. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2001, 15:14 |
|
||
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
2 Genady Да, ещё. Я бы всё ж не стал использовать суммирование ошибки по Вашему методу, потому что 1) Ошибки (в соответствии с MSDN) могут иметь отрицательные коды а значит вместо сложения может произойти вычитание и 2) Если у меня в начале произошёл сбой, требующий отката транзакции, то зачем мне продолжать выполнять инструкции, которые я всё-равно собираюсь откатить ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2001, 15:24 |
|
||
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
1. Вот что интересно: если пишем на С, то проверять результаты операций if (func1()==FAIL){... - это нормально, а в T-SQL - нет. Если и говорить, то о механизме исключений (точнее обработки), но чего нет, того нет. 2. В sysmessages я отрицательных значений error не встречал, если только Вы не вставите своё. Но вообще-то для них зарезервированы ?? > 50000. 3. У Вас существует возможность начать транзакцию на клиенте, инициировать выполнение SP и по возвращённому результату принять решение об отмене или записи транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2001, 19:49 |
|
||
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
Прос Суммирование кода ошибок... @Error = @error + abs(@@error) Вот так приблизительно обходятся отрицательные коды ошибок... moth@mail.primorye.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2001, 02:03 |
|
||
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
Проблема все же по моему мнению надумана и не стоит суеты Не нравится суммирование ошибок, делайте откат после каждого инсерта/апдейта. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2001, 05:25 |
|
||
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
А можно set @Error = @Error | @@Error вместо плюса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2001, 08:56 |
|
||
|
А как же транзакции???
|
|||
|---|---|---|---|
|
#18+
Господа, ну чего Вы обсуждаете, ну причём здесь суммирование ошибок, или нормально или не нормально проверять ошибки после каждой операции? Ну причём здесь всё это, вопрос ведь совсем в другом. Итак, чтобы не вызвать ураган рекомендаций по суммированию кодов ошибок, которое мне совсем не нужно, максимально упрощаю свой вопрос: RAISERROR меняет статус системы в SQL-запросе, устанавливая при этом код и уровень ошибки. Клиент всегда знает эти коды, можно ли их узнать в SQL-запросе, чтобы максимально эффективно и надёжно обрабатывать транзакции в SQL-процедурах? Это же так просто, естественно и очевидно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.07.2001, 12:36 |
|
||
|
|

start [/forum/topic.php?fid=46&fpage=3559&tid=1826098]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
24ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
39ms |
get tp. blocked users: |
1ms |
| others: | 218ms |
| total: | 320ms |

| 0 / 0 |
