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

Откуда: Саратов
Сообщений: 467
Доброе утро, коллеги!
https://msdn.microsoft.com/en-us/library/ms188792.aspx
Не кажется ли вам странным то, что по умолчанию
XACT_ABORT выставлен в OFF ?

+ Чуть измененный пример с MSDN

DECLARE @XACT_ABORT VARCHAR(3) = 'OFF';  
IF ( (16384 & @@OPTIONS) = 16384 ) SET @XACT_ABORT = 'ON';  
SELECT @XACT_ABORT AS XACT_ABORT;  
GO
IF OBJECT_ID(N't2', N'U') IS NOT NULL  
    DROP TABLE t2;  
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  
--блок 5
BEGIN TRY
    BEGIN TRANSACTION;  
    INSERT INTO t2 VALUES (1);  
    INSERT INTO t2 VALUES (2); -- Foreign key error.  
    INSERT INTO t2 VALUES (3);  
    COMMIT TRANSACTION;  
END TRY
BEGIN CATCH
    ROLLBACK TRAN 
    THROW
END CATCH
GO
select *from t2
GO  
--блок 6
INSERT INTO t2 
VALUES (4), (6), (5);  
GO  
SELECT *  
    FROM t2;  
GO  



Т.о. мы начинаем транзакцию (блок 5), получаем в ходе нее ошибку и вместо того чтобы полностью откатить, мы по умолчанию делаем частичную фиксацию.
Не кажется ли вам, что здесь скомпрометировано само понятие транзакции?

С другой стороны, в блоке 6 мы не открываем явно транзакцию, однако из-за значения 5 инструкция откатывается полностью.
21 мар 17, 09:00    [20316160]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
aleksrov
Member

Откуда:
Сообщений: 948
Шамиль Фаридович,

Вот здесь подробный дебаты были на эту тему
https://www.sql.ru/forum/1244473-2/ischeznovenie-dannyh-v-tablicah-baz-dannyh
21 мар 17, 09:05    [20316170]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
o-o
Guest
от нас что требуется, подтвердить, что черезж..пно сделано
или сказать, что причиной этому умолчанию(off) является legacy?
21 мар 17, 10:37    [20316465]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Вот тут сказали, что в SQL 2016 исправили: Зачем нужен rollback, если есть commit?
21 мар 17, 10:40    [20316480]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
iap
Вот тут сказали, что в SQL 2016 исправили: Зачем нужен rollback, если есть commit?

посмотрел на дев 2016, стоит OFF и в msdn пишет для него OFF is the default setting.
21 мар 17, 10:44    [20316488]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
Шамиль Фаридович
Member

Откуда: Саратов
Сообщений: 467
В 2016 XACT_ABORT по умолчанию OFF, подтверждаю.
Забавно, что я в своем скрипте допустил ошибку - в блоке CATCH не хватает ";" после ROLLBACK TRAN, и в итоге я не откатил транзакцию))
Таким образом при использовании TRY-CATCH откатывается вся транзакция вне зависимости от XACT_ABORT - вполне ожидаемое поведение.
Вопрос снят.
21 мар 17, 11:17    [20316695]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
Шамиль Фаридович
Member

Откуда: Саратов
Сообщений: 467
o-o
от нас что требуется, подтвердить, что черезж..пно сделано
или сказать, что причиной этому умолчанию(off) является legacy?

Типа того)
Учитывая пример
Mind
BEGIN TRY 
	BEGIN TRAN
	SELECT * FROM nonexisting_table
	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK
	RAISERROR('А мне глубоко насрать на ваш обработчик ошибок!', 16, 10)
END CATCH
GO

SELECT @@TRANCOUNT


логичнее было бы иметь по умолчанию XACT_ABORT ON.
Но тут вероятно дело в обратной совместимости.
21 мар 17, 11:51    [20316919]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Шамиль Фаридович,

в SSMS2016 по умолчанию ON. Специально проверял после установки.
21 мар 17, 14:05    [20317670]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Владислав Колосов
Шамиль Фаридович,

в SSMS2016 по умолчанию ON. Специально проверял после установки.

ну ладно, для начала, при чём здесь SSMS2016?
21 мар 17, 14:13    [20317720]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
TaPaK,

наверное, в этом фикс и заключался :)
21 мар 17, 16:44    [20318449]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
лолл
Member

Откуда:
Сообщений: 450
Шамиль Фаридович
o-o
от нас что требуется, подтвердить, что черезж..пно сделано
или сказать, что причиной этому умолчанию(off) является legacy?

Типа того)
Учитывая пример
Mind
BEGIN TRY 
	BEGIN TRAN
	SELECT * FROM nonexisting_table
	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK
	RAISERROR('А мне глубоко насрать на ваш обработчик ошибок!', 16, 10)
END CATCH
GO

SELECT @@TRANCOUNT


логичнее было бы иметь по умолчанию XACT_ABORT ON.
Но тут вероятно дело в обратной совместимости.


Такие ошибки можно отловить, но уже на более высоком уровне выполнения:

CREATE PROC A
AS
BEGIN TRY 
	BEGIN TRAN
	SELECT * FROM nonexisting_table
	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK
	RAISERROR('А мне глубоко насрать на ваш обработчик ошибок!', 16, 10)
END CATCH
GO

BEGIN TRY
  EXEC A
END TRY
BEGIN CATCH
  IF @@TRANCOUNT > 0
    ROLLBACK;
  THROW;
END CATCH
GO
SELECT @@TRANCOUNT;

DROP PROC A
21 мар 17, 18:31    [20318806]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1142
получается что теперь уже и хранимку просто так не вызовешь без анализа счетчика транзакций, тоже не особо логично :)
имхо, запуская хранимку я рассчитываю на то что она либо отработает полностью, либо вывалится с ошибкой откатив абсолютно все изменения сделанные в процессе своего выполения :)
22 мар 17, 11:32    [20320487]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
энди
получается что теперь уже и хранимку просто так не вызовешь без анализа счетчика транзакций, тоже не особо логично :)
имхо, запуская хранимку я рассчитываю на то что она либо отработает полностью, либо вывалится с ошибкой откатив абсолютно все изменения сделанные в процессе своего выполения :)
о дивный новый мир... о чём ты?
22 мар 17, 11:41    [20320524]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1142
Да вон выше пример как человек хранимку запускает обернув ее в try catch и анализом счетчика транзакций и все это для того чтобы посути "exec a" сделать :)
22 мар 17, 11:47    [20320563]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
энди
Да вон выше пример как человек хранимку запускает обернув ее в try catch и анализом счетчика транзакций и все это для того чтобы посути "exec a" сделать :)
вы ничего не поняли
22 мар 17, 11:51    [20320581]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
лолл
Member

Откуда:
Сообщений: 450
энди,

я лишь показал, что в данном случае не обязательно писать SET XACT_ABORT ON, можно делать контроль отката на более высоком уровне исполнения, хоть бы и на уровне вашего приложения, где формируется начальный запрос.
22 мар 17, 12:04    [20320656]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1142
да нет, я понял что это из-за xact_abort, просто выглядит такая конструкция жутковато
22 мар 17, 12:08    [20320667]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
Nimua
Member

Откуда: Ростов-на-Дону
Сообщений: 344
Мне кажется просто для отката транзакции без обработки ошибок нужен только Set XACT_ABORT ON;
Я не очень понимаю зачем сочетать и SET XACT_ABORT ON и TRY CATCH.
Кроме есть особенность когда их пишешь вместе, вот кусок из книжки

Itzik Ben-Gan, Ron Talmage, Dejan Sarka Training Kit (Exam 70-461): Querying Microsoft SQL Server 2012
автор
Using XACT_ABORT with TRY/CATCH
XACT_ABORT behaves differently when used in a TRY block. Instead of terminating the transaction
as it does in unstructured error handling, XACT_ABORT transfers control to the CATCH
block, and as expected, any error is fatal. The transaction is left in an uncommittable state
(and XACT_STATE() returns a –1). Therefore, you cannot commit a transaction inside a CATCH
block if XACT_ABORT is turned on; you must roll it back.
The XACT_STATE() values are:
■■ 1 An open transaction exists that can be either committed or rolled back.
■■ 0 There is no open transaction; it is equivalent to @@TRANCOUNT = 0.
■■ -1 An open transaction exists, but it is not in a committable state. The transaction can
only be rolled back.
Within the CATCH block, you can determine the current transaction nesting level with the
@@TRANCOUNT system function.
If you have nested transactions, you can retrieve the state of the innermost transaction
with the XACT_STATE function.
22 мар 17, 13:56    [20321170]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
o-o
Guest
Nimua
Мне кажется просто для отката транзакции без обработки ошибок нужен только Set XACT_ABORT ON;
Я не очень понимаю зачем сочетать и SET XACT_ABORT ON и TRY CATCH.


set xact_abort on;
go

begin tran
   create table dbo.test(id int);
   exec('select');
commit; 

select *
from dbo.test;

таблица существует на конец выполнения кода.
никуда ее создание не откатилось.
если обернете все в try..catch и в catch сделаете откат, то откатится
22 мар 17, 14:33    [20321386]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
Nimua
Member

Откуда: Ростов-на-Дону
Сообщений: 344
o-o,

в вашем примере да - отката не произойдет

Однако, если сделать вот так:

set xact_abort on;

declare @id int;

begin tran
   create table dbo.test(id int);
   SET @id = 1/0
commit; 

select *
from dbo.test;


То все откатится.

Я сначала думала, что severity не тот, но нет - 15. Возможно дело в exec и динамическом sql - думала как то может ошибка не передается, однако

set xact_abort on;


begin tran
   create table dbo.test(id int);
   exec ('declare @id int; SET @id = 1/0');
commit; 

select *
from dbo.test;

--drop table dbo.test;


это тоже откатит транзакцию. Возможно причина в Syntax error в вашем примере, хотя возвращаемый severity 15, что означает что транзакция должна откатиться автоматом.

вот из той же книжки ограничения по XACT_ABORT

You set XACT_ABORT per session. After it is set to
ON, all remaining transactions in that setting are subject to it until it is set to OFF.
SET XACT_ABORT has some advantages. It causes a transaction to roll back based on any
error with severity > 10.
However, XACT_ABORT has many limitations, such as the following:
1 You cannot trap for the error or capture the error number.
2 Any error with severity level > 10 causes the transaction to roll back.
3 None of the remaining code in the transaction is executed. Even the final PRINT statements
of the transaction are not executed.
4 After the transaction is aborted, you can only infer what statements failed by inspecting
the error message returned to the client by SQL Server.
22 мар 17, 14:59    [20321471]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
o-o
Guest
Nimua
Однако, если сделать вот так:
То все откатится.
...
хотя возвращаемый severity 15, что означает что транзакция должна откатиться автоматом

вы же хотели увидеть пример того,
где недостаточно выставить xact_abort on.
разумеется, не любая ошибка проканает,
а именно ошибка компиляции.
severity тут ни при чем
22 мар 17, 15:07    [20321511]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
Nimua
Member

Откуда: Ростов-на-Дону
Сообщений: 344
o-o,

поняла, спасибо,

Мне все еще не понятно, почему это не вызывает откат транзакции.
То есть идее он должен происходить. Я в том смысле, что я не вижу в описании и в инструкции того, что могло бы намекнуть, что такие ошибки не вызовут откат.

https://technet.microsoft.com/ru-ru/library/ms188792(v=sql.105).aspx

Разве только вот это "Значение параметра XACT_ABORT устанавливается во время выполнения, а не во время синтаксического анализа." Но это в любом случае неожиданно для меня.

Спасибо за пример!
22 мар 17, 15:12    [20321538]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Nimua,

XACT_STATE показывает что будет
22 мар 17, 15:13    [20321545]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
o-o
Guest
Nimua

Мне все еще не понятно, почему это не вызывает откат транзакции.
То есть идее он должен происходить.

потому что error handling в SQL Server это сущий бардак.
и описание severity тоже
22 мар 17, 15:15    [20321564]     Ответить | Цитировать Сообщить модератору
 Re: XACT_ABORT  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Описание гласит, что откат происходит при рантайм ошибках, о времени компиляции речи нет.
Поэтому и нет отката в примере о-о.
23 мар 17, 11:17    [20324601]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить