powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / А как же транзакции???
9 сообщений из 9, страница 1 из 1
А как же транзакции???
    #32009054
Фотография Serge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
        Господа, я понимаю, конечно, что я лопух и чего-то не догоняю, но именно поэтому я и задаю здесь свой вопрос. А вопрос заключается вот в чём. Насколько я понимаю, сермяжная суть механизма транзакций заключается в том, что набор действий (выборка данных, изменения в таблицах и т.д.), ограничиваемый транзакцией, либо выполняется ВЕСЬ , либо не выполняется ВООБЩЕ . Для меня это было интуитивно очевидно, пока я не столкнулся со следующей ситуацией, поясню её на примере:

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" после каждой маломальски серьёзной инструкции?
        В общем, я в полной прострации и буду находиться в ней, пока кто-нибудь не подскажет мне, как мне бороться с этой ситуацией и чего я здесь, лопух, не догоняю. А ведь мне позарез надо написать довольно ответственную базу данных.
...
Рейтинг: 0 / 0
А как же транзакции???
    #32009058
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
...
Рейтинг: 0 / 0
А как же транзакции???
    #32009076
Фотография Serge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
        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.
...
Рейтинг: 0 / 0
А как же транзакции???
    #32009077
Фотография Serge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
        2 Genady
        Да, ещё. Я бы всё ж не стал использовать суммирование ошибки по Вашему методу, потому что
        1) Ошибки (в соответствии с MSDN) могут иметь отрицательные коды
а значит вместо сложения может произойти вычитание и
        2) Если у меня в начале произошёл сбой, требующий отката транзакции, то зачем мне продолжать выполнять инструкции, которые я всё-равно собираюсь откатить
...
Рейтинг: 0 / 0
А как же транзакции???
    #32009082
Fompro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Вот что интересно: если пишем на С, то проверять результаты операций if (func1()==FAIL){... - это нормально, а в T-SQL - нет. Если и говорить, то о механизме исключений (точнее обработки), но чего нет, того нет.
2. В sysmessages я отрицательных значений error не встречал, если только Вы не вставите своё. Но вообще-то для них зарезервированы ?? > 50000.
3. У Вас существует возможность начать транзакцию на клиенте, инициировать выполнение SP и по возвращённому результату принять решение об отмене или записи транзакции.
...
Рейтинг: 0 / 0
А как же транзакции???
    #32009108
Moth
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прос Суммирование кода ошибок...

@Error = @error + abs(@@error)

Вот так приблизительно обходятся отрицательные коды ошибок...

moth@mail.primorye.ru
...
Рейтинг: 0 / 0
А как же транзакции???
    #32009116
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема все же по моему мнению надумана и не стоит суеты

Не нравится суммирование ошибок, делайте откат после каждого инсерта/апдейта.
...
Рейтинг: 0 / 0
А как же транзакции???
    #32009137
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно set @Error = @Error | @@Error вместо плюса.
...
Рейтинг: 0 / 0
А как же транзакции???
    #32010226
Фотография Serge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
        Господа, ну чего Вы обсуждаете, ну причём здесь суммирование ошибок, или нормально или не нормально проверять ошибки после каждой операции? Ну причём здесь всё это, вопрос ведь совсем в другом.
        Итак, чтобы не вызвать ураган рекомендаций по суммированию кодов ошибок, которое мне совсем не нужно, максимально упрощаю свой вопрос:
         RAISERROR меняет статус системы в SQL-запросе, устанавливая при этом код и уровень ошибки. Клиент всегда знает эти коды, можно ли их узнать в SQL-запросе, чтобы максимально эффективно и надёжно обрабатывать транзакции в SQL-процедурах?
        Это же так просто, естественно и очевидно.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / А как же транзакции???
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]