MSSQL Ошибка 3930: Current transaction cannot be committed — Doomed Transaction
- Сообщение:
Msg 3930, Level 16, State 1: The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction. - В 1С падает проведение документов или регламентное задание с ошибкой «Транзакция отменена».
- Наличие необработанной ошибки внутри блока
TRY...CATCHпри включенном параметреXACT_ABORT ON. - В логе транзакция переходит в статус нефиксации (Doomed / Uncommittable State).
1. Анализ механизма Doomed Transaction
Ошибка 3930 возникает, когда внутри транзакции происходит ошибка уровня серьезности (Severity), которая переводит транзакцию в состояние, где возможен только полный откат (ROLLBACK), но код пытается выполнить COMMIT или новые операции записи в лог.
2. Проверка состояния транзакции через XACT_STATE()
В любых хранимых процедурах, триггерах и прямых запросах к SQL Server внедрите проверку функции XACT_STATE():
BEGIN TRY
BEGIN TRANSACTION;
-- Бизнес-логика 1С / SQL
UPDATE [dbo].[_Document123] SET [_Fld456] = 1 WHERE [_IDRRef] = 0x12345;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Проверка состояния транзакции
IF (XACT_STATE()) = -1
BEGIN
-- Транзакция не может быть зафиксирована, только откат
ROLLBACK TRANSACTION;
END
ELSE IF (XACT_STATE()) = 1
BEGIN
-- Транзакция активна и валидна
COMMIT TRANSACTION;
END;
-- Повторный вызов ошибки для фиксации в журнале 1С
THROW;
END CATCH;
GO3. Проверка параметров SET XACT_ABORT
Если в коде или триггерах используется SET XACT_ABORT ON, любая ошибка времени выполнения немедленно делает транзакцию нефиксируемой. Убедитесь, что логика обработки ошибок учитывает это поведение.
Частые вопросы (FAQ)
Что возвращает функция XACT_STATE()?
1 = Транзакция активна и готова к фиксации (COMMIT); 0 = Нет открытых транзакций; -1 = Транзакция повреждена (Doomed) и может быть только полностью откачена (ROLLBACK).
Почему 1С генерирует ошибку 3930 при работе с фоновыми заданиями?
Если фоновое задание превышает таймаут блокировки или перехватывает дедлок (Deadlock Error 1205) внутри неявной транзакции 1С, транзакция помечается как uncommittable, и последующий вызов ЗафиксироватьТранзакцию() вызовет 3930.
Можно ли сохранить часть данных, если транзакция получила XACT_STATE = -1?
Нет. При переходе в это состояние запись в файл LDF полностью блокируется ядром СУБД. Единственная допустимая операция — ROLLBACK TRANSACTION.
Влияет ли Distributed Transaction Coordinator (MSDTC) на эту ошибку?
Да, при сбое связи с координатором распределенных транзакций во время 2-phase commit распределенная транзакция немедленно переходит в состояние -1.