Задание SQL имеет проблемы с журналом транзакций

У меня есть задание SQL, которое просто выполняет хранимую процедуру. Каждое утро, когда задание пытается запуститься, я получаю следующую ошибку:

Текущая транзакция не может быть зафиксирована и не поддерживает операции записи в файл журнала.

Когда я продолжаю пытаться перезапустить задание, оно продолжает выдавать ту же ошибку. Однако, если я просто выполняю процедуру сохранения без использования задания, все работает нормально.

И вот действительно очень сложная часть. Если я просто запускаю хранимую процедуру, отменяю ее, а затем запускаю задание, задание работает отлично.

Кто-нибудь сталкивался с этой довольно уникальной проблемой или есть какие-либо идеи, что может быть ее причиной?


person Justin Balvanz    schedule 24.06.2009    source источник
comment
можешь выложить код процедуры.   -  person Raj More    schedule 24.06.2009
comment
Не совсем. Это довольно длительные процессы. Часть, которая просто поставила меня в тупик, заключается в том, что у меня никогда не бывает проблем с выполнением самой процедуры, но у агента есть проблемы. И тогда агент сможет запустить его после того, как я его запущу.   -  person Justin Balvanz    schedule 24.06.2009


Ответы (2)


Эта ошибка указывает на то, что вы пытаетесь выполнить зарегистрированную операцию во время обреченной транзакции. Это может произойти только в блоке BEGIN CATCH, если вы игнорируете XACT_STATE значение -1:

Текущий запрос имеет активную пользовательскую транзакцию, но произошла ошибка, из-за которой транзакция была классифицирована как незафиксированная транзакция. Запрос не может зафиксировать транзакцию или выполнить откат к точке сохранения; он может только запросить полный откат транзакции. Запрос не может выполнять какие-либо операции записи, пока не откатит транзакцию. Запрос может выполнять только операции чтения, пока не откатит транзакцию. После отката транзакции запрос может выполнять операции чтения и записи, а также начинать новую транзакцию.

Тот факт, что вы пытаетесь это сделать, просто указывает на проблему кода с обработкой исключений (другими словами, ваша процедура содержит ошибки). Недавно я писал в своем блоге о шаблоне для процедур, использующих BEGIN TRY /BEGIN CATCH, и вы можете использовать это как отправную точку для исправления вашей процедуры. У Эрланда Соммарскога есть известная статья об обработке ошибок Transact-SQL, но это не охватывает BEGIN TRY/BEGIN CATCH слишком глубоко.

При правильной обработке ошибок вы сможете обнаружить исходную ошибку, которая возникает и приводит к выполнению вашего блока CATCH в первую очередь. Поскольку вы упомянули, что запуск процедуры вручную не вызывает проблем, проблема, вероятно, заключается в различиях в контексте между заданием агента SQL и вашим ручным выполнением. Я не могу диагностировать проблему без каких-либо данных, но я предполагаю, что наиболее вероятной причиной является разница в контексте безопасности (т. е. логину агента не хватает некоторых прав, которые есть у вашего собственного логина).

person Remus Rusanu    schedule 24.06.2009
comment
Первая статья в порядке, но я думаю, что есть лучший способ. Либо я, либо мой коллега по MVP скоро опубликую статью - person gbn; 24.06.2009

Я получал эту ошибку при разных условиях, и я придумал короткий путь репликации (дефект программного обеспечения отсутствует IF XACT_STATE() != 1 ROLLBACK):

-- prepare SP

IF OBJECT_ID(N'ShortReplicationPath',N'P') IS NOT NULL     DROP PROCEDURE dbo.ShortReplicationPath
GO

CREATE PROCEDURE dbo.ShortReplicationPath
AS 

BEGIN  
    BEGIN TRY   

        insert #TempTabDateTime (ValidFrom) Values ('date')

    END TRY

    BEGIN CATCH

        PRINT ERROR_NUMBER();        PRINT ERROR_MESSAGE();

    INSERT INTO     #TempTabVarChar
    (       Text    )
    VALUES  (       'abcdefg'   )

    END CATCH

END 

GO

-- Execute test:

IF OBJECT_ID ('TEMPDB..#TempTabDateTime') IS NOT NULL drop table #TempTabDateTime

create table #TempTabDateTime (ValidFrom DATETIME)

IF OBJECT_ID ('TEMPDB..#TempTabVarChar') IS NOT NULL drop table #TempTabVarChar

create table #TempTabVarChar (Text VarChar(MAX))

BEGIN TRANSACTION

    EXEC dbo.ShortReplicationPath
ROLLBACK

GO
person Mike    schedule 02.11.2010