Hangfire:Azure SQL:添加新作业失败

3

出现以下错误:

内部异常:"对象引用未设置为对象的实例。" 堆栈跟踪: at System.Transactions.Transaction.GetPromotedToken()

即使我在下面的代码中将enlist=false设置在连接字符串中,该错误仍来自于connection.EnlistTransaction(Transaction.Current)这一行。

   `internal T UseTransaction<T>([InstantHandle] Func<DbConnection, DbTransaction, T> func, IsolationLevel? isolationLevel)
    {
     #if NETFULL
        using (var transaction = CreateTransaction(isolationLevel ?? _options.TransactionIsolationLevel))
        {
            var result = UseConnection(connection =>
            {
                connection.EnlistTransaction(Transaction.Current);
                return func(connection, null);
            });

            transaction.Complete();

            return result;
        }
}`

当我们设置enlist=true时,下面代码中的connection.Open()会出现错误。

    internal DbConnection CreateAndOpenConnection()
    {
        if (_existingConnection != null)
        {
            return _existingConnection;
        }

        var connection = new SqlConnection(_connectionString);
        connection.Open();

        return connection;
    }

这两种方法都在Hangfire.SqlServer.SqlServerStorage类下面。

当连接到本地数据库(SQL Server 2014)时,相同的代码可以工作。

在讨论WCF事务针对Azure SQL DB中,不确定是否与此问题相关。

编辑:

HangFire配置

GlobalConfiguration.Configuration.UseSqlServerStorage(
                Database.ConnectionString,
                new SqlServerStorageOptions
                {
                    QueuePollInterval = TimeSpan.FromSeconds(10),
                    PrepareSchemaIfNecessary = true
                });

任务排队

BackgroundJob.Enqueue(() => Update(connectionToken, intFileUniqueId));

Please help. Thanks in advance.


嗨,添加了HangFire配置和作业排队的代码片段!!! - Kaushal Shah
BackgroundJob.Enqueue(x => x.Update(connectionToken, intFileUniqueId)); x是什么?你能否添加包装Enqueue行的代码? - Kim Hoang
这只是一个Lambda表达式,Enqueue函数将“action”作为参数传递:var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!")); - Kaushal Shah
我已经完全做了同样的事情,这不是问题,因为相同的代码库适用于本地 SQL Server 2014 数据库,问题只出现在 Azure SQL 数据库的情况下。 正如我在问题描述中提到的,我怀疑它与 Azure 不支持分布式事务有关。 但是,在这方面,我有些怀疑,因为“Enqueue”在某些其他功能中可以正常工作,但仅对于此功能而言失败,并且如果交易是问题,它可能应该在运行作业时失败而不是添加作业时失败。 困惑!!! - Kaushal Shah
如果本地可以运行,但在AzureSQL上无法运行,则很可能是使用了Azure不支持的功能。例如,AzureSQL不支持分布式事务。 - Simon Halsey
显示剩余4条评论
1个回答

1
发现问题了。调用方法将作业排队的代码在事务中,这会导致分布式事务,而Azure SQL不支持它。
考虑下面的代码:
    public override void UpdateFile(int intUniqueId)
    {
        using (var scope = GetTransactionScope(...))
        {
             QueueJob<Updater>(x => x.Update(token, intUniqueId));
            scope.Complete();
        }
    }


    private static void QueueJob<T>(Expression<Action<T>> action)
    {
            BackgroundJob.Enqueue(action);
    }

在被调用方法中移除事务范围是有效的。我正在检查是否需要事务范围,如果不需要,我将移除它。!!!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接