【问题标题】:Hangfire: Azure SQL: Adding a new job is failingHangfire:Azure SQL:添加新作业失败
【发布时间】:2017-01-13 10:22:03
【问题描述】:

得到以下错误

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

错误来自线路connection.EnlistTransaction(Transaction.Current);在下面的代码中,即使我在连接字符串中设置了 enlist=false。

   `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 Transaction against Azure SQL DB,不确定是否与此问题相关。

编辑:

HangFire 配置

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

工作队列

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

请帮忙。 提前致谢。

【问题讨论】:

  • 可以在添加 Hanfire 作业的地方添加代码吗?
  • 嗨,添加了 HangFire 配置和作业入队代码 sn-ps!!!
  • BackgroundJob.Enqueue(x => x.Update(connectionToken, intFileUniqueId));什么是 x,你能不能也添加比 enqueue 行换行的代码。
  • 这只是一个 Lambda 表达式,Enqueue 函数接受一个“动作”作为参数: var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!"));进一步更新...
  • 通常,在运行作业时,Hangfire 需要创建一个“x”对象的实例,然后使用参数的序列化值调用 x 对象的更新。所以问题可能来自那个x的类型。通常我所做的是创建一个名为 BackgroundProcess 的单独类,并使用无参数构造函数,并将我的后台方法放入其中。

标签: distributed-transactions hangfire azure-sql-database


【解决方案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);
    }

在被调用方方法中删除事务范围有效。 我正在检查事务范围的必要性,如果不需要,我将其删除。!!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多