Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Триггер на таблице1 производит изменения в таблице2.

Я исхожу из того, что в случае возникновения любой ошибки при изменении в таблице2, данные в таблице1 так же откатятся.
Вот схема.
CREATE TABLE deffTest1 (ID int )
GO
CREATE TABLE deffTest2 (ID int)
GO

CREATE TRIGGER tgTst1 ON deffTest1
FOR INSERT, UPDATE
AS
set nocount on

INSERT INTO deffTest2 --Если на этой операции возникнет ошибка с уровнем 16(и выше) или rollback, то изменения на deffTest1 также откатятся. (?)
SELECT ID from inserted
GO

INSERT INTO deffTest1 VALUES(1)
GO

Вроде все работает как надо. Однако крайне редко менятеся только таблица1, без изменений в таблице2.
Что я не учел?

Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) Feb 9 2007 22:47:07 Copyright (c) 1988-2005 Microsoft Corporation Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
1 июн 11, 12:04    [10744146]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Триггер всегда работает в транзакции с командой, меняющей данные в таблице. А вот транзакция откатывается не при любой ошибке, даже с уровнем 16.
1 июн 11, 12:07    [10744170]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Я считал что любая ошибка при вставке в таблицу 2, констрейны в основном, ключи(триггеров instead нету на таблице два) должна вызвать Rollback?
Или лучше написать
CREATE TRIGGER tgTst1 ON deffTest1
FOR INSERT, UPDATE
AS
set nocount on
/*Вот тут блок проверок, но все идут в виде */
IF /*проверка=плохо*/
   BEGIN
  	rollback tran
  	raiserror('Все плохо', 16,16)
  	return
   END
 
INSERT INTO deffTest2 
SELECT ID from inserted

/*Может сдеть тоже сделать проверку?*/
If @@Error<>0
   BEGIN
  	rollback tran
  	raiserror('Все плохо', 16,16)
  	return
   END
GO
1 июн 11, 12:21    [10744299]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Во-первых, есть xact_abort. Во-вторых, try/catch. Если ни тем, ни другим не пользоваться, то да, придется делать примерно то, что у вас. Только опять же, в триггере транзакцию откатывать не кошерно.
1 июн 11, 12:23    [10744320]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
А я что-то не уверен что нужно. Наглядный пример в студию.
Как я понимаю, нарушение счётчика транзакций это существенная ошибка. Или я ошибаюсь?
1 июн 11, 12:29    [10744390]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
BOL: http://msdn.microsoft.com/en-us/library/ms188792(v=sql.100).aspx#1
Connect: http://connect.microsoft.com/SQLServer/feedback/details/405350/xact-abort-and-triggers
1 июн 11, 12:36    [10744472]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Спасибо за помощь. Не буду забывать вставлять везде set xact_abort on. Думаю решит проблему.
А по поводу что не кошерно - может быть.
Это на самом деле защита от программиста. Триггеры так сделаны, что бы сохранить целостность данных, даже при ошибочных действиях программиста. Заставить программиста пользоваться только хранимками крайне тяжело. А за ALTER TABLE DISABLE TRIGGER - сразу отрубаем руки.
Есть и еще плюсы в такой системе, но это уже отдельная темя для разговора.
1 июн 11, 12:37    [10744477]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Mnior
А я что-то не уверен что нужно. Наглядный пример в студию.
Как я понимаю, нарушение счётчика транзакций это существенная ошибка. Или я ошибаюсь?

Это вам. Потом говорите про нарушение счетчика.
CREATE TABLE deffTest1 (ID int )
GO
CREATE TABLE deffTest2 (ID int)
GO

CREATE TRIGGER tgTst1 ON deffTest1
FOR INSERT, UPDATE
AS
set nocount on

SELECT @@TRANCOUNT
GO

INSERT INTO deffTest1 VALUES(1)
GO
1 июн 11, 12:38    [10744496]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Deff
Спасибо за помощь. Не буду забывать вставлять везде set xact_abort on. Думаю решит проблему.
А по поводу что не кошерно - может быть.
Это на самом деле защита от программиста. Триггеры так сделаны, что бы сохранить целостность данных, даже при ошибочных действиях программиста. Заставить программиста пользоваться только хранимками крайне тяжело. А за ALTER TABLE DISABLE TRIGGER - сразу отрубаем руки.
Есть и еще плюсы в такой системе, но это уже отдельная темя для разговора.
У программиста можно и нужно на боевом сервере отобрать права, чтобы у него не было выбора.
1 июн 11, 12:39    [10744509]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Mnior
BOL: http://msdn.microsoft.com/en-us/library/ms188792(v=sql.100).aspx#1
С этим все понятно. Как устроены транзакции я знаю.
1 июн 11, 12:42    [10744542]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Deff
Не буду забывать вставлять везде set xact_abort on.
Вы не читали что я привёл.

Deff
Это вам. Потом говорите про нарушение счетчика.
Кто-бы говорил. Не врубились совсем.
USE tempdb
GO
CREATE TABLE dbo.Test1 (ID Int Identity)
GO
CREATE TABLE dbo.Test2 (ID Int Identity)
GO
CREATE TABLE dbo.Test3 (ID Int Identity)
GO
CREATE TRIGGER tgTst1 ON dbo.Test1
FOR INSERT AS BEGIN
	PRINT '1,1:';PRINT @@TranCount
	INSERT dbo.Test2 DEFAULT VALUES
	PRINT '1,2:';PRINT @@TranCount
	INSERT dbo.Test3 DEFAULT VALUES
	PRINT '1,3:';PRINT @@TranCount
END
GO
CREATE TRIGGER tgTst2 ON dbo.Test2
FOR INSERT AS BEGIN
	PRINT '2,1:';PRINT @@TranCount
	ROLLBACK
	PRINT '2,2:';PRINT @@TranCount
END
GO
INSERT dbo.Test1 DEFAULT VALUES
GO
SELECT * FROM dbo.Test1
SELECT * FROM dbo.Test2
SELECT * FROM dbo.Test3
GO
DROP TABLE dbo.Test3
DROP TABLE dbo.Test2
DROP TABLE dbo.Test1
GO
1 июн 11, 12:47    [10744585]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Deff
Mnior
BOL: http://msdn.microsoft.com/en-us/library/ms188792(v=sql.100).aspx#1
С этим все понятно. Как устроены транзакции я знаю.

Я извиниюсь, это как раз то, что нужно. Не откатывается транзакция при ошибке Foreign key error.
Наглядное подтверждение.

Надо использовать SET XACT_ABORT ON. Что я просто забыл сделать

Спасибо.
1 июн 11, 12:47    [10744589]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Гавриленко Сергей Алексеевич
У программиста можно и нужно на боевом сервере отобрать права, чтобы у него не было выбора.
У бедных контор во время кризиса - свои правила)
Я имею перегруженный сервер. Практически пустую бета-базу, что не способствет написанию актульного кода для огромных бд. Отсуствие нормального бета-тестирования.
1 июн 11, 12:54    [10744645]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Mnior,
Я понял теперь, что вы хотели сказать про транкаунт.

Я не буду делать такую проверку
If @@Error<>0
   BEGIN
  	rollback tran
  	raiserror('Все плохо', 16,16)
  	return
   END
1 июн 11, 13:01    [10744719]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Deff
Mnior
BOL: http://msdn.microsoft.com/en-us/library/ms188792(v=sql.100).aspx#1
С этим все понятно. Как устроены транзакции я знаю.
Вы не поняли:
CREATE TRIGGER tgTst1 ON dbo.Test1
FOR INSERT AS BEGIN
	SET XACT_ABORT OFF;
	PRINT '1,1:';PRINT @@TranCount
	INSERT dbo.Test2 DEFAULT VALUES
	PRINT '1,2:';PRINT @@TranCount
	INSERT dbo.Test3 DEFAULT VALUES
	PRINT '1,3:';PRINT @@TranCount
END
GO
Пофигу т.к:
SET XACT_ABORT OFF is not allowed in triggers when compatibility level is 90 or above.
1 июн 11, 13:01    [10744724]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Deff
Надо использовать SET XACT_ABORT ON. Что я просто забыл сделать
В процедурах можно (лучше) писать TRY/CATCH (и забить на XACT_ABORT).
1 июн 11, 13:05    [10744759]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Mnior
Пофигу т.к:
SET XACT_ABORT OFF is not allowed in triggers when compatibility level is 90 or above.

А вот что то глючит у меня.
IF OBJECT_ID(N't2', N'U') IS NOT NULL
    DROP TABLE t2;
GO
IF OBJECT_ID(N't1', N'U') IS NOT NULL
    DROP TABLE t1;
GO
CREATE TABLE t1
    (a INT NOT NULL PRIMARY KEY);
CREATE TABLE t2
    (a INT NOT NULL REFERENCES t1(a));
GO
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (3);
INSERT INTO t1 VALUES (4);
INSERT INTO t1 VALUES (6);
GO

CREATE TRIGGER tgTst1 ON t1
FOR INSERT, UPDATE
AS
set nocount ON
SET XACT_ABORT off
INSERT INTO t2 VALUES (1);
INSERT INTO t2 VALUES (2); -- Foreign key error.
INSERT INTO t2 VALUES (3);
GO

INSERT INTO t1 VALUES (7);--Запускаю триггер.

GO
SELECT *
    FROM t2;
GO
1 июн 11, 13:40    [10745126]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
На двух базах - разный результат. Обе написано что 9ые.
1 июн 11, 13:40    [10745132]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Вы можете посмотреть на tempdb. ТОже написано что 90.
1 июн 11, 13:42    [10745161]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
А есть такие ошибки, которые не вызовут откат транзакции даже при set xact_abort on?

Мне кажется TRY/CATCH менее удобно.
1 июн 11, 14:36    [10745774]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Вообщем проблема была в другом.
Причина аварийное отключение сервера сразу по завершению транзакции или во время транзакции.
Так что от ресета нет спасения. Еще раз в этом убедился.
Ранее, кстати, с кем-то спорил на этот счет. Он не верил, что могут пропасть данные, и при этом база не будет считаться поврежденной.
Пропадает действительно часть транзакции.
1 июн 11, 15:11    [10746121]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Deff
Вообщем проблема была в другом.
Причина аварийное отключение сервера сразу по завершению транзакции или во время транзакции.
Так что от ресета нет спасения. Еще раз в этом убедился.
Ранее, кстати, с кем-то спорил на этот счет. Он не верил, что могут пропасть данные, и при этом база не будет считаться поврежденной.
Пропадает действительно часть транзакции.
Да что-то как-то не верится, если честно.
1 июн 11, 15:17    [10746204]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Deff
А вот что то глючит у меня.
Mnior
Как я понимаю, нарушение счётчика транзакций это существенная ошибка.
Замечание веское.
Уже понадеялся и поверил (легко т.к. пофигу и не влияет) что поменялось. Тогда всё нормально и вернулось на старые места.

Так вы в курсе, что при вызове выполняемого объекта (процедура триггер) сохраняется счётчик транзакций и при выходе проверяется?
Была даже соответствующая ошибка. Подробнее.
1 июн 11, 15:30    [10746378]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Deff
Так что от ресета нет спасения. Еще раз в этом убедился.
Врёте.
Где-то у вас код затесался без транзакций.
1 июн 11, 15:32    [10746401]     Ответить | Цитировать Сообщить модератору
 Re: Триггер и транзакции.  [new]
Deff
Member

Откуда: Пермь
Сообщений: 18328
Гавриленко Сергей Алексеевич
Deff
Вообщем проблема была в другом.
Причина аварийное отключение сервера сразу по завершению транзакции или во время транзакции.
Так что от ресета нет спасения. Еще раз в этом убедился.
Ранее, кстати, с кем-то спорил на этот счет. Он не верил, что могут пропасть данные, и при этом база не будет считаться поврежденной.
Пропадает действительно часть транзакции.
Да что-то как-то не верится, если честно.
Правда. У нас куча локальных серверов. Ребутятся часто. Сталкиваюсь не в первый раз.

Вот еще.
https://www.sql.ru/blogs/decolores/949
2. Для размещения файлов транзакционного лога требуются быстрые носители.
Скорость выполнения запроса на изменение данных зависит самым главным образом именно от скорости диска, на котором размещен файл журнала. Поскольку сами данные пишутся в фоновом режиме, то для большинства систем требования по производительности диска, обслуживающего файлы данных будут ниже. На сегодняшний день требования такие: время выполнения дискового запроса к файлу лога должно укладываться (ориентировочно) в 5-10 миллисекунд, запроса к файлу данных - в 10-20 миллисекунд. Разные источники приводят разные конкретные значения этого показателя, но в любом случае для файла лога очень критична быстрая запись.
....
С другой стороны, если ваш SQL Server установлен на "Desktop" с Windows7, XP или в системе установлены недорогие "бытовые" диски, то кэширование возможно будет включено и без поддерживания кэша батарейкой. Поэтому часто обычные компьютеры в роли сервера к удивлению администратора работают быстрее, чем на первый взгляд более мощные «настоящие» серверные компьютеры. Но эта разница в производительности достигается за счет снижения надежности - "вовремя" нажатая кнопка Reset или скачек напряжения могут разрушить базы данных.
1 июн 11, 15:34    [10746425]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить