Почему Microsoft SQL Server неявно выполняет откат при сбое оператора CREATE? - PullRequest
2 голосов
/ 04 мая 2011

Я работаю над pymssql, драйвером Python MSSQL. Я столкнулся с интересной ситуацией, для которой я не могу найти документацию. Похоже, что при сбое оператора CREATE TABLE транзакция, в которой он был выполнен, неявно откатывается:

-- shows 0
select @@TRANCOUNT
BEGIN TRAN

-- will cause an error
INSERT INTO foobar values ('baz')

-- shows 1 as expected
select @@TRANCOUNT

-- will cause an error
CREATE TABLE badschema.t1 (
    test1 CHAR(5) NOT NULL
)

-- shows 0, this is not expected
select @@TRANCOUNT

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

Примечание

Меня не интересует типичное поведение транзакций. Я специально хочу знать, почему неявный откат дается в случае неудачного оператора CREATE, но не с оператором INSERT.

Ответы [ 3 ]

1 голос
/ 04 мая 2011

Вот полное руководство по обработке ошибок на Sql Server:
http://www.sommarskog.se/error-handling-I.html

Это долго, но в хорошем смысле, и оно было написано для Sql Server 2000, но большая часть его все еще точна. Часть, которую вы ищете, находится здесь:
http://www.sommarskog.se/error-handling-I.html#whathappens

В вашем случае в статье говорится, что Sql Server выполняет пакетный аборт , и что он примет эту меру в следующих ситуациях:

  • Большинство ошибок преобразования, например, преобразование нечисловой строки в числовое значение.
  • Лишний параметр для хранимой процедуры без параметров.
  • Превышение максимального уровня вложенности хранимых процедур, триггеров и функций.
  • Быть выбранным в качестве жертвы тупика.
  • Несоответствие количества столбцов в INSERT-EXEC.
  • Недостаточно места для файла данных или журнала транзакций.

В этом есть нечто большее, поэтому обязательно прочитайте весь раздел.

1 голос
/ 04 мая 2011

Если вы запускаете как один пакет (что я делал в первый раз), транзакция остается открытой, потому что INSERT прерывает пакет, а CREATE TABLE не запускается. Только если вы запускаете построчно, транзакция откатывается

Вы также можете создать неявный откат для INSERT, установив SET XACT_ABORT ON.

Мое предположение (только что был момент лампочки, когда я набрал предложение выше), что CREATE TABLE использует SET XACT_ABORT ON internalls = неявный откат на практике

Еще кое-что от меня на SO о SET XACT_ABORT (мы используем его во всем нашем коде, потому что он снимает блокировки и откатывает TXN на клиентском CommandTimeout)

1 голос
/ 04 мая 2011

Часто, но не всегда, точка транзакции откатывает всю вещь , если какая-либо ее часть терпит неудачу : http://www.firstsql.com/tutor5.htm

Одна из наиболее распространенных причин использования транзакций - это когда действие должно быть атомарным:

Атомная операция в компьютере наука относится к множеству операций которые могут быть объединены так, чтобы они кажется, что остальная часть системы одна операция только с двумя возможные результаты: успех или неудача. en.wikipedia.org/wiki/Atomic_(computer_science)

Вероятно, это не задокументировано, потому что, если я правильно понимаю ваш пример, предполагается, что вы намеревались реализовать эту функцию, начав транзакцию с BEGIN TRAN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...