Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Нормально ли так ?  [new]
Вадим Ж.
Guest
Подскажите пожалуйста .
Нужно срочно сделать.
Нормально ли так обрабабатывать ошибки в триггере :
BEGIN TRY 
 /*что- то делаем */

END TRY 
BEGIN CATCH 
  ROLLBACK TRAN 
DECLARE @String nvarchar(max)
SET @String = ERROR_MESSAGE()
 RAISERROR(@String, 16, 100) 
 RETURN 
END  CATCH 


А в процедуре которая вызваза триггер обработка :
 IF XACT_STATE() <> 0 
  COMMIT / ROLLBACK TRAN 
19 авг 09, 18:02    [7558277]     Ответить | Цитировать Сообщить модератору
 Re: Нормально ли так ?  [new]
Вадим Ж.
Guest
Или лучше не откатывать транзакцию в триггере ? А вызвавшая процедура должна обработать ошибку и решть что делать с траназкцией.
Подскажите пожалуйста.

Спасибо.
19 авг 09, 21:27    [7558761]     Ответить | Цитировать Сообщить модератору
 Re: Нормально ли так ?  [new]
aklerk
Member

Откуда:
Сообщений: 66
Вадим Ж.,

Хороший пример:
http://msdn.microsoft.com/en-us/library/ms189797.aspx
20 авг 09, 11:10    [7560328]     Ответить | Цитировать Сообщить модератору
 Re: Нормально ли так ?  [new]
aklerk
Member

Откуда:
Сообщений: 66
Вадим Ж.,

только в вашем случае проверять XACT_STATE() нет смысла:
SET XACT_ABORT ON;

BEGIN TRY
	BEGIN TRANSACTION;
	INSERT INTO [dbo].[tbTestTriggerRollback] VALUES (1)
	COMMIT TRANSACTION;
END TRY
BEGIN CATCH
END CATCH;
при условии, что в триггере может быть ROLLBACK
20 авг 09, 11:17    [7560392]     Ответить | Цитировать Сообщить модератору
 Re: Нормально ли так ?  [new]
Вадим Ж.
Guest
Так у меня нету SET XACT_ABORT ON;
Дело в том что у меня срабатывние триггера будет из вложенный процедуры. И каждая вложенная проверяет наличие транзакции и только если ее нет , то открывает. И тело каждой оборнуто в try/catch c регенерацией ошибки. Таким образом самая верхняя процедура получит ошибку. И уже на основании XACT_STATE() определит есть ли еще транзакция и в каком она состоянии. Вопрос в другом, верно ли откатывать транзакцию прямо в триггере или правельнее просто регенрерить в нем ошибку , а вызвавшая процедура сама должна разрулить свои транзакции ?
20 авг 09, 13:08    [7561327]     Ответить | Цитировать Сообщить модератору
 Re: Нормально ли так ?  [new]
aklerk
Member

Откуда:
Сообщений: 66
Вадим Ж.,

Да, правильно. Потому что триггер ВСЕГДА выполняется в рамках транзакции команды, его вызвавшей! Хотите вы его или нет. А дальше Вы должны сами решить, где должен быть ROLLBACK (и как обрабатывать ошибку), что определяется серверной логикой. Не забывайте, текущая процедура может быть не единственной, вызывающей срабатывание триггера.
Из Вашего объяснения можно представить множество порядков команд (или, правильнее в данном случае - транзакций). Поясните подробнее. Что-то мне указывает на возможность вложенных транзакций, но не уверен, что я правильно Вас понял
20 авг 09, 14:57    [7562172]     Ответить | Цитировать Сообщить модератору
 Re: Нормально ли так ?  [new]
Вадим Ж.
Guest
Вложенная процедура запускающая триггер :
CREATE PROCEDURE dbo.prNested
AS 
DECLARE @TranNeed bit 
BEGIN TRY

IF @@TRANCOUNT = 0
  SET @TranNeed = 1
ELSE 
  SET @TranNeed = 0 

IF @TranNeed = 0 
 BEGIN TRAN 

  /*<здесь операция приводящая к выполнению триггера> */

IF @TranNeed = 1 
 COMMIT TRAN 
END TRY 
BEGIN CATCH
  IF @TranNeed = 1 AND XACT_STATE <> 0 
     ROLLBACK TRAN 

 declare @string nvarchar(max)  

set @string = ERROR_MESSAGE() 

 RAISERROR(@string , 16, 100)
 RETURN 

END CATCH 
А вот основная процедура
CREATE PROCEDURE dbo.prTopLevel
AS
DECLARE @TranNeed bit
BEGIN TRY

IF @@TRANCOUNT = 0
SET @TranNeed = 1
ELSE
SET @TranNeed = 0

IF @TranNeed = 0
BEGIN TRAN

EXEC dbo.prNested


IF @TranNeed = 1
COMMIT TRAN
END TRY
BEGIN CATCH
IF @TranNeed = 1 AND XACT_STATE <> 0
ROLLBACK TRAN

declare @string nvarchar(max)

set @string = ERROR_MESSAGE()

RAISERROR(@string , 16, 100)

RETURN


END CATCH
[/src]
Триггер привед в первом посте. И тот же вопрос : где лучше делать rollback в триггере или в нем только регенерацию ошибки ?
20 авг 09, 16:36    [7562962]     Ответить | Цитировать Сообщить модератору
 Re: Нормально ли так ?  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
лучше по идее в триггере. тогда будет обеспечиваться транзакционность, если вдруг забудете повесить обработку ошибок..

для спящего время бодрствования равносильно сну
20 авг 09, 16:53    [7563077]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить