1

我有一个简单地执行存储过程的 SQL 作业。每天早上,当作业尝试运行时,我都会收到以下错误:

当前事务无法提交,并且无法支持写入日志文件的操作。

当我继续尝试重新开始工作时,它一直给我同样的错误。但是,如果我只执行存储过程而不使用 Job,它就可以正常工作。

这是真正非常棘手的部分。如果我只是运行存储过程,取消它,然后运行作业,那么作业就可以正常工作了。

有没有人遇到过这个相当独特的问题或有任何想法可能导致它?

4

2 回答 2

3

此错误表明您正在尝试在注定的事务期间执行记录操作。如果您忽略 -1 的XACT_STATE值,这只会发生在 BEGIN CATCH 块中:

当前请求有一个活动的用户事务,但发生了一个错误,导致该事务被归类为不可提交事务。请求无法提交事务或回滚到保存点;它只能请求事务的完全回滚。该请求在回滚事务之前不能执行任何写操作。该请求只能执行读取操作,直到它回滚事务。事务回滚后,请求可以执行读取和写入操作,并且可以开始新事务。

您尝试执行此操作的事实仅表明您的异常处理存在代码问题(换句话说,您的过程有问题)。我最近写了一篇关于使用 BEGIN TRY/BEGIN CATCH 的程序模板的博客,您可以将其用作修复程序的起点。Erland Sommarskog 有一篇关于 Transact-SQL 错误处理的著名文章,但这并没有太深入地介绍 BEGIN TRY/BEGIN CATCH。

通过适当的错误处理,您可以找出发生的原始错误并导致您的 CATCH 块首先被执行。由于您提到手动运行该过程不会导致任何问题,因此问题可能是 SQL 代理作业和您的手动执行之间的上下文差异。我无法在没有任何数据的情况下诊断问题,但我猜测最可能的原因是安全上下文的差异(即代理登录缺少您自己的登录所拥有的某些权限)。

于 2009-06-24T16:41:04.063 回答
1

我在不同的条件下遇到了这个错误,我想出了一个简短的复制路径(缺少软件缺陷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
于 2010-11-02T21:04:20.190 回答