Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как объявлять транзакции в хранимой процедуре?  [new]
Alvas
Member

Откуда:
Сообщений: 71
Есть процедура с телом типа

=========
DELETE FROM price_brackets WHERE project_id = @ProjectID
DELETE FROM print_order WHERE project_id = @ProjectID
DELETE FROM project WHERE project_id = @ProjectID

GO
=========

Она гнется на последнем DELETE. По идее должен произойти откат, то есть ни из одной таблицы не должны удалиться данные.
А они удаляются из 2-предыдущих таблиц.
Как поправить чтобы или изо всех таблиц удалялись данные или происходил откат транзакции?
19 мар 03, 19:12    [151692]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74925
Попробуй так:
SET XACT_ABORT ON


BEGIN TRAN

DELETE FROM price_brackets WHERE project_id = @ProjectID
DELETE FROM print_order WHERE project_id = @ProjectID
DELETE FROM project WHERE project_id = @ProjectID

COMMIT TRAN
19 мар 03, 19:14    [151694]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
Сергей Тихонов
Member

Откуда: Киев
Сообщений: 787
Лучше всего, чтобы транзакция начиналась и заканчивалась на клиенте...
19 мар 03, 21:01    [151737]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
Gobzo Kobler
Member

Откуда: у людей такая фантазия?
Сообщений: 387
Alvas: с какой базы перешел на сиквел? Поди, с интербейс? Здесь надо начинать и заканчивать транзакцию руками, проверять @@ERROR после каждого выражения, которое может вызвать ошибку времени исполнения, и принимать решение. А лучше всего почитать книжку про MS SQL.
19 мар 03, 22:15    [151768]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
Коляныч
Member

Откуда:
Сообщений: 279
Сергей Тихонов: Лучше всего, чтобы транзакция начиналась и заканчивалась на клиенте...

чем лучше?
20 мар 03, 06:17    [151860]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Можно и книжку почитать...
Я вот всё не пойму эти пытливые умы...
Блин, да погляди же в процедуры от производителя - как он пишет тразакции, как блокировки...
20 мар 03, 07:08    [151885]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
Alex_2003_
Guest
Можно так:

BEGIN TRANSACTION
DELETE FROM price_brackets WHERE project_id = @ProjectID
IF(@@ERROR<>0) GOTO ERR_HANDLER
DELETE FROM print_order WHERE project_id = @ProjectID
IF(@@ERROR<>0) GOTO ERR_HANDLER
DELETE FROM project WHERE project_id = @ProjectID
IF(@@ERROR<>0) GOTO ERR_HANDLER
COMMIT TRANSACTION
ERR_HANDLER:
IF(@@TRANCOUNT > 0)
ROLLBACK TRANSACTION
RETURN 0
20 мар 03, 08:10    [151911]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74925
2 Alex_2003_

Использование IF(@@ERROR<>0) оправдано при разлиции в обработке ошибок после различных инструкций внутри транзакции. А в Вашей ситуации вариант с SET XACT_ABORT ON идентичен по обработке Вашему последнему листингу.
20 мар 03, 08:25    [151919]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
mart
Member

Откуда:
Сообщений: 33
Если нужно, чтобы внешняя транзакция не откатывалась, а только откатилась работа блока, выполняемого в процедуре, то можно так, при этом конечно должен быть XACT_ABORT OFF

CREATE PROCEDURE P_##_PROC_NAME
-- <params>

AS
DECLARE
@_error int
BEGIN
--******************************************

DECLARE
@__trancount int,
@__tranname varchar(32)
SELECT
@__trancount = @@TRANCOUNT,
@__tranname = REPLACE(CONVERT(varchar(36),NEWID()),'-','')
IF @__trancount = 0 BEGIN TRANSACTION
ELSE SAVE TRANSACTION @__tranname
--******************************************

-- Полезная работа

SELECT 1/0

SET @_error = @@ERROR
IF @_error <> 0 GOTO EXCEPTION

--******************************************

IF @__trancount = 0 COMMIT TRANSACTION
RETURN 0
EXCEPTION:
IF @__trancount = 0 ROLLBACK TRANSACTION
ELSE ROLLBACK TRANSACTION @__tranname
RETURN @_error
--******************************************

END
20 мар 03, 09:05    [151956]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
funikovyuri
Member

Откуда: Симферополь
Сообщений: 4045
Делайте как сказал pkarklin
2mart: по моему это какая-то попытка написания платформенно независимого кода - текста много - толку меньше
20 мар 03, 10:14    [152047]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
tygra
Member

Откуда: Тверь (Иркутск, Край)
Сообщений: 9997
2 Сергей Тихонов

Лучше всего, чтобы транзакция начиналась и заканчивалась на клиенте...

Вас специально в составе диверсионной группы забросили чтоли, чтобы такие ответы давать и морочить людям голову?
20 мар 03, 11:01    [152135]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
Alvas
Member

Откуда:
Сообщений: 71
Всем спасибо!

Помогло...

Gobzo Kobler: Перехожу из под Оракла
21 мар 03, 15:39    [153683]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
Сергей Тихонов
Member

Откуда: Киев
Сообщений: 787
> tygra, Коляныч
Я придерживаюсь своего мнения. По тому как бывают ситуации, когда SET XACT_ABORT ON вас не спасет. Например, когда один из операторов процедуры в run-time приводит к ошибке, при которой процедура вываливается сразу... Конечно, такие вещи можно выявлять при тестировании, но... и палка раз в жизнь стреляет.
Повторяю еще раз: стартовать и завершать / откатывать транзакции лучше на клиенте. Это дает вам необходимую дистанцию при работе и 100% гарантию подтверждения / отката в любой ситуации. В случае же, когда на самом интересном месте пропадет коннект, то сервер откатит все за вас...
21 мар 03, 22:20    [154007]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
MiCe
Member

Откуда: RUSSIA STAVROPOL Pyatigorsk
Сообщений: 1996
2 Сергей Тихонов
ага.... база чел эдак на 50..
время транзакции выходит длиннее.... лишние блокировки.....
люди ждут , ругаются , программера "добрым" словом вспоминают.....
ну или клиент начал транзакцию.... коннект не пропал, а завершить забыл(ну или через пол часа вспомнит)
22 мар 03, 11:33    [154108]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Это дает вам необходимую дистанцию при работе и 100% гарантию подтверждения / отката в любой ситуации Картинка с другого сайта.
А если на сервере все это делается, то что - никакой гарантии нет, что ли? А?
Это значит - руки кривые, если на сервере нельзя грамотно транзакцию разрулить. Где гарантия, что она и на клиенте не обгадится?Картинка с другого сайта.
22 мар 03, 11:44    [154110]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
gringo
Member

Откуда: Nizny Novgorod
Сообщений: 76
>ну или клиент начал транзакцию.... коннект не пропал, а завершить забыл(ну или через пол часа вспомнит)
это кто такие программы пишет? Чтобы пользователь начинал и сам завершал транзакции безконтрольно? Да это завесит все что угодно.
22 мар 03, 11:45    [154111]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74925
2 Сергей Тихонов

По тому как бывают ситуации, когда SET XACT_ABORT ON вас не спасет. Например, когда один из операторов процедуры в run-time приводит к ошибке, при которой процедура вываливается сразу...

Так в 99.9% случаев это имеено то, что и нужно. А если нужна другая обработка, то извольте IF @@ERROR <> 0...

Повторяю еще раз: стартовать и завершать / откатывать транзакции лучше на клиенте. Это дает вам необходимую дистанцию при работе и 100% гарантию подтверждения / отката в любой ситуации. В случае же, когда на самом интересном месте пропадет коннект, то сервер откатит все за вас...

И 100% гарантию подвисающих транзакций, типа кофе пошел попить со всеми вытекающими отсюда последствиями.

А за письмо спасибо.
22 мар 03, 11:47    [154113]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Кто, кто... Тот, наверное, кто транзакцию на клиента и переносит.
22 мар 03, 11:47    [154114]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
gringo
Member

Откуда: Nizny Novgorod
Сообщений: 76
Транзакции на клиенте - IMHO, вполне нормальное дело? другое дело, как их писать
22 мар 03, 12:12    [154118]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74925
>другое дело, как их писать

Абсолютно согласен. Сам ими пользуюсь. Но здесь речь шла о транзакциях внутри хп. Так что, замечания, типа на клиенте лучше, тут не причем.
22 мар 03, 12:17    [154120]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
MiCe
Member

Откуда: RUSSIA STAVROPOL Pyatigorsk
Сообщений: 1996
просто это не хороший вариант для клиента....
а вот для реализации "среднего звена" (midle tier) в трех звенке иногда
может понадобится.... обсобленно если серверов sql два.....
22 мар 03, 12:46    [154123]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
2 mart
Слушай, ну ты даешь!!! Картинка с другого сайта.
(только щаЗ внимательно код глянул)

Поддерживаю funikovyuri.
Это ж как таЛЛантливА написанА:
.

.
.
IF @__trancount = 0 COMMIT TRANSACTION
RETURN 0
EXCEPTION:
IF @__trancount = 0 ROLLBACK TRANSACTION
.
.
.

Это как понимать? Если число транзакций = 0, тогда завершить транзакцию... Если число транзакций = 0, тогда откатить транзакцию с точки сохранения транзакции.
Т.е., если число транзакций больше нуля, тогда - ну их нафиг, пусть болтаются, что ли?
И, что, в "полезной работе" проверять ошибки не надо? @@ERROR ведь обнуляется перед выполнением очередного оператора (сорри за повторение банальности).
22 мар 03, 12:48    [154124]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
Сергей Тихонов
Member

Откуда: Киев
Сообщений: 787
> MiCe
Ага, эдак человек на 250-300 + филиалы... Но это неважно...

> tpg
Я не говорил о том, что транзакцию нельзя в ХП разрулить... Я высказал свое ИМХО... И насчет кривых рук я был бы поакуратнее...

> All
Никто не говорил, что транзакция с клиента - это транзакция, стартуемая и завершаемая живым человеком, поэтому реплики "пошел кофе пить..." неуместны. Транзакции стартует и завершает / откатывает клиентское приложение (двухзвенка), либо арр-сервер (трехзвенка)...
24 мар 03, 11:47    [154585]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
Дамир
Guest
Народ! А как узнать текущую установку XACT_ABORT ?
select XACT_ABORT - не проходит.
3 апр 03, 09:08    [163240]     Ответить | Цитировать Сообщить модератору
 Re: Как объявлять транзакции в хранимой процедуре?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74925
2 Дамир

А зачем тебе знать то. Ставь, что тебе надо ON/OFF.
3 апр 03, 09:15    [163245]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить