微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在NHibernate中为长期运行的任务分配事务和会话范围

如何解决在NHibernate中为长期运行的任务分配事务和会话范围

|| 在Web应用程序中使用NHibernate时,我通常会让IoC容器负责按请求打开和关闭ѭ0并提交/回滚事务。 HTTP的性质使在此类应用程序中定义清晰的工作单元变得非常容易。 现在,我的任务是组装一个小程序,该程序将由任务调度程序定期调用以发送新闻通讯。新闻稿和订阅者的概念在我们的域模型中已经是定义明确的实体,向所有订阅者发送新闻稿将涉及以下操作:
var subscribers = _session
    .QueryOver<Subscription>()
    .Where(s => !s.HasReceivednewsletter)
    .List();

foreach (var subscriber in subscribers)
{
    SendNewsletterTo(subscriber);
    subscriber.HasReceivednewsletter = true;
}
注意每个“ 2”对象如何在循环中更新,记录她现在已收到时事通讯。这个想法是,如果邮件发送程序崩溃了,则可以重新启动它,并从中断处继续发送新闻通讯。 我面临的问题是在此处定义和实现工作单元模式。在循环的每次迭代结束之前,我可能需要将更改提交到数据库。简单地用3块包装循环体似乎在运行时间上非常昂贵,而且我似乎还遇到了长时间运行的过程与使用同一数据库的其他(Web)应用程序之间的锁定问题。 在阅读了有关NHibernate事务的一些文章和文档之后,我开始想到,我可能需要从会话中分离出订户列表,以避免锁定问题,然后将它们重新附加到循环主体中的新会话中。不过,我不确定这将如何提高性能。 那么,NHibernate专家,您将如何设计和实施像这样长期运行的工作?     

解决方法

您不认为无事务的无状态会话在这里会更好吗?     ,您不想在这里使用异步持久消息吗?诸如NServiceBus,Rhino服务总线或MassTransit之类的东西。看来您不必尽快发送大量消息,因此我认为您应该以每用户1条持久消息的异步方式进行发送     ,一个会话中有多个事务没有问题。在此将交易范围限定为更新单个订户是适当的,因为它是独立的操作。根据订阅者的数量和失败的可能性,最好一次捕获少量的订阅者。
foreach (var subscriber in subscribers)
{
    using (var txn = _session.BeginTransaction())
    {
        try
        {
            SendNewsletterTo(subscriber);
            subscriber.HasReceivedNewsletter = true;
            txn.Commit();
        }
        catch (Exception ex)
        {
            txn.Rollback();
            // log exception,clean up any actions SendNewsletterTo has taken if needed
            // Dispose of session and start over
        }   
    }
}
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。