В чем выгода использования SET XACT_ABORT ON
хранимой процедуры?
sql
sql-server
odiseh
источник
источник
Ответы:
SET XACT_ABORT ON
указывает SQL Server выполнить откат всей транзакции и прервать пакет при возникновении ошибки во время выполнения. Он охватывает вас в таких случаях, как тайм-аут команды, возникающий в клиентском приложении, а не в самом SQL Server (который не предусмотренXACT_ABORT OFF
настройкой по умолчанию ).Так как тайм-аут запроса оставит транзакцию открытой,
SET XACT_ABORT ON
рекомендуется во всех хранимых процедурах с явными транзакциями (если у вас нет особых причин делать иначе), поскольку последствия выполнения приложением работы над соединением с открытой транзакцией катастрофичны.В блоге Дэна Гусмана есть отличный обзор ,
источник
BEGIN TRY
-BEGIN CATCH
иROLLBACK
сBEGIN CATCH
блоком в Sql?BEGIN TRY
-BEGIN CATCH
не будет отлавливать такие вещи, как тайм-аут, возникающий в клиентском приложении, и некоторые ошибки SQL также невозможно отследить, оставляя вас с открытой транзакцией, которую вы не ожидаете.По моему мнению, SET XACT_ABORT ON устарел благодаря добавлению BEGIN TRY / BEGIN CATCH в SQL 2k5. До блоков исключений в Transact-SQL было действительно трудно обрабатывать ошибки, и несбалансированные процедуры были слишком распространены (процедуры, у которых при выходе отличался @@ TRANCOUNT по сравнению с входом).
С добавлением обработки исключений в Transact-SQL стало намного проще писать правильные процедуры, которые гарантированно обеспечивают правильный баланс транзакций. Например, я использую этот шаблон для обработки исключений и вложенных транзакций :
Это позволяет мне писать атомарные процедуры, которые откатывают только свою собственную работу в случае исправимых ошибок.
Одной из основных проблем, с которыми сталкиваются процедуры Transact-SQL, является чистота данных : иногда полученные параметры или данные в таблицах просто неверны, что приводит к ошибкам дублирующихся ключей, ошибкам ограничения ссылок, ошибкам проверки ограничений и т. Д. И т. Д. В конце концов, именно в этом и заключается роль этих ограничений: если бы эти ошибки чистоты данных были бы невозможны и все они были пойманы бизнес-логикой, ограничения были бы все устаревшими (резкое преувеличение добавлено для эффекта). Если XACT_ABORT включен, то все эти ошибки приводят к потере всей транзакции, в отличие от возможности кодировать блоки исключений, которые корректно обрабатывают исключение. Типичный пример - попытка сделать INSERT и возврат к UPDATE при нарушении PK.
источник
Цитирование MSDN :
На практике это означает, что некоторые операторы могут потерпеть неудачу, оставив транзакцию «частично завершенной», и для вызывающей стороны может не быть никаких признаков этого сбоя.
Простой пример:
Этот код будет выполнен «успешно» с выключенным XACT_ABORT и завершится с ошибкой с XACT_ABORT ON («INSERT INTO t2» не будет выполнен, и клиентское приложение вызовет исключение).
В качестве более гибкого подхода вы можете проверять @@ ERROR после каждого оператора (старая школа) или использовать блоки TRY ... CATCH (MSSQL2005 +). Лично я предпочитаю устанавливать XACT_ABORT ON всякий раз, когда нет причин для какой-либо сложной обработки ошибок.
источник
Что касается тайм-аутов клиентов и использования XACT_ABORT для их обработки, по моему мнению, есть, по крайней мере, одна очень веская причина иметь тайм-ауты в клиентских API, таких как SqlClient, и это защищать код клиентского приложения от тупиков, возникающих в коде SQL-сервера. В этом случае в клиентском коде нет ошибки, но он должен сам защитить себя от блокировки, ожидающей завершения команды на сервере. И наоборот, если для защиты клиентского кода должны существовать тайм-ауты клиента, то XACT_ABORT ON должен защищать код сервера от аварий клиента, в случае, если выполнение кода сервера занимает больше времени, чем клиент готов ждать.
источник
Он используется в управлении транзакциями, чтобы гарантировать, что любые ошибки приведут к откату транзакции.
источник