与NHibernate集成Quartz .NET

5

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


我认为这不是Quartz.Net的有效用例。你能更具体一些吗?你想向Quartz.Net作业传递额外的自定义数据,还是想更新自己的数据库?请记住,Quartz.Net作业可能在NHibernate事务关闭后很长时间才会触发,因此您不能在作业中重用现有事务(最好的方法是通过获取ISessionFactory在作业中打开新会话)。 - yorah
1个回答

3

我对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尊重事务范围,并默认这样做吗? - Timo
请注意,某些连接器将使用相同的实际连接,并且不会分布式事务,只要事务中的所有连接都使用“完全相同”的连接字符串(直到最后一个空格)。我知道的两个示例是针对 MySql 的,即 Oracle 连接器和真正异步的 MySqlConnector。这样的连接器将与您的代码示例非常匹配。 - Timo

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