【问题标题】:Integrate Quartz .NET with NHibernate将 Quartz .NET 与 NHibernate 集成
【发布时间】:2013-08-07 21:39:57
【问题描述】:

我已经安装了 Quartz .NET 并创建了 Quartz 数据库。我需要使用我自己的自定义数据来扩展 Quartz 作业存储。例如,当我通过 Quartz API 添加作业时,我需要在同一个数据库事务中将其他信息添加到我自己的自定义表中。我知道 Quartz 中有一个名为 JobStoreCMT 的类,但我找不到任何简洁的示例来展示如何为 Quartz 提供 NHibernate 创建的事务。

【问题讨论】:

  • 我认为这不是 Quartz.Net 的有效用例。你可以说得更详细点吗?您想将额外的自定义数据传递给您的 Quartz.Net 作业,还是想更新您自己的数据库?请记住,在您的 NHibernate 事务关闭后很长时间可能会触发 Quartz.Net 作业,因此您不能在作业中重用现有事务(您可以做的最好的事情是在您的作业中打开一个新会话,通过获取持有 ISessionFactory)。

标签: .net nhibernate quartz.net


【解决方案1】:

我对 JobStoreCMT 的理解是,您使用 .NET 2.0 中引入的 System.Transactions 命名空间中的类来声明所有事务。幸运的是 NHibernate 也可以很好地处理这些事务,因此您可以将 Quartz 操作和 NHibernate 操作放在单个 TransactionScope 中,如下所示:

using (var ts = new TransactionScope()) {

    // do something with your scheduler here, eg
    _scheduler.ScheduleJob(someJobDetail, someTrigger);

    // create an NHibernate session that will be part of the same transaction
    using (var session = _sessionFactory.OpenSession()) {

        // perform actions on session here, but do *not* make use of
        // NHibernate transaction methods, such as ISession.BeginTransaction(),
        // because the transaction is controlled via the TransactionScope instance.

    }

    ts.Complete();
}

上面的代码假定在其他地方声明并初始化了以下变量:

Quartz.IScheduler _scheduler;
NHibernate.ISessionFactory _sessionFactory;

上面的代码示例没有详细说明,但这是大体思路。

您可能遇到的一个问题是上述代码需要分布式事务,因为 Quartz JobStoreCMT 类创建一个数据库连接,而 NHibernate 会话创建另一个数据库连接。虽然有可能(至少使用 SQL Server)让两个不同的数据库连接共享同一个事务,但我的理解是 System.Transactions 的当前实现将通过打开第二个连接将事务升级为分布式事务。这将对性能产生重大影响,因为分布式事务比简单事务要慢得多。

【讨论】:

  • 很好的答案。只是为了确保,您确定 Quartz 尊重事务范围,并且默认情况下这样做?
  • 请注意,有某些连接器将使用相同的实际连接并且没有分布式事务,只要事务中的所有连接都使用 exact 相同的连接字符串(向下到最后一个空格)。我知道的两个示例是针对 MySql 的,即 Oracle 连接器和真正异步的 MySqlConnector。这样的连接器将是您的代码示例的理想选择。
猜你喜欢
  • 2014-08-16
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
  • 2010-12-03
  • 1970-01-01
  • 2011-12-05
相关资源
最近更新 更多