我有一个简单执行存储过程的SQL作业。每天早上当作业尝试运行时,我都会收到以下错误:
当前事务无法提交,也无法支持写入日志文件的操作。
当我不断尝试重新启动作业时,它一直给我同样的错误。但是,如果我只是在不使用Job的情况下执行存储过程,它可以正常工作。
这是非常棘手的部分。如果我只是运行存储过程,取消它,然后运行作业,工作完全正常。
有没有人遇到这个相当独特的问题,或者有任何想法可能导致它?
答案 0 :(得分:3)
此错误表示您正在尝试在注定的事务期间执行记录操作。如果您忽略-1的XACT_STATE值,则只能在BEGIN CATCH块中发生:
当前请求具有活动用户 事务,但发生了错误 导致交易的原因 被列为不可置信的 交易。请求无法提交 交易或回滚到 保存点;它只能要求一个完整的 回滚交易。该 请求无法执行任何写入 操作直到它回滚 交易。请求只能 执行读取操作直到它滚动 支持交易。之后 交易已经回滚了 请求可以执行读取和 写操作,可以开始新的 事务。
您尝试执行此操作仅表示您的异常处理存在代码问题(换句话说,您的过程是错误的)。我最近在博客上发表了关于a template for procedures that use BEGIN TRY/BEGIN CATCH的博文,您可以将其作为修复程序的起点。 Erland Sommarskog有a well known article on Transact-SQL error handling,但这并没有涵盖BEGIN TRY / BEGIN CATCH太深。
通过适当的错误处理,您可以找出发生的原始错误并使您的CATCH块首先执行。由于您提到手动运行该过程不会导致任何问题,因此问题可能是SQL代理作业与手动执行之间的上下文差异。我无法在没有任何数据的情况下诊断问题,但我猜测最可能的原因是安全上下文的差异(即,代理登录缺少您自己的登录所具有的权利)。
答案 1 :(得分: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