永远保持开放状态吗? [英] Keep an nihbernate session open forever?

查看:87
本文介绍了永远保持开放状态吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用石英和休眠型,遇到了问题.通常,我会在Web请求完成时关闭所有nhibernate会话,但是我有一个从应用程序启动开始的调度程序,因此我需要传递一个我认为永远不应关闭的nhibernate会话.

I am using quartz and nhibernate and ran into a problem. Normally I have all my nhibernate sessions close on finish of a web request but I have a scheduler that starts on application start and I need to pass in a nhibernate session that I think should never be closed.

我不确定该怎么做.

注入

 public class NhibernateSessionFactoryProvider : Provider<ISessionFactory>
    {   
        protected override ISessionFactory CreateInstance(IContext context)
        {
            var sessionFactory = new NhibernateSessionFactory();
            return sessionFactory.GetSessionFactory();
        }
    }

  public class NhibernateModule : NinjectModule
    {
        public override void Load()
        {
            Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
            Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
        }
    }

Global.aspx

Global.aspx

  protected void Application_Start()
    {
        // Hook our DI stuff when application starts
        IKernel kernel = SetupDependencyInjection();

        // get the reminder service HERE IS WHERE THE PROBLEMS START
        IScheduledRemindersService scheduledRemindersService = kernel.Get<IScheduledRemindersService>();

        scheduledRemindersService.StartTaskRemindersSchedule();

        RegisterMaps.Register();

        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);


    }


    public IKernel SetupDependencyInjection()
    {
        IKernel kernel = CreateKernel();
        // Tell ASP.NET MVC 3 to use our Ninject DI Container
        DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));

        return kernel;
    }

    protected IKernel CreateKernel()
    {
        var modules = new INinjectModule[]
                          {
                             new NhibernateModule(),
                             new ServiceModule(),
                             new RepoModule()
                          };

        return new StandardKernel(modules);
    }

//导致我出现问题的服务. Ninject将绑定hinterRepo并为其进行一次会话.

// service that is causing me the problems. Ninject will bind reminderRepo and give it an nihbernate session.

private readonly IReminderRepo reminderRepo;
private readonly ISchedulerFactory schedulerFactory;

public ScheduledRemindersService(IReminderRepo reminderRepo)
{
    this.reminderRepo = reminderRepo;
    schedulerFactory = new StdSchedulerFactory();
}

public void StartTaskRemindersSchedule()
{

    IScheduler scheduler = schedulerFactory.GetScheduler();

    scheduler.Start();

    JobDetail jobDetail = new JobDetail("TaskRemindersJob",null,typeof(TaskReminderJob));
    jobDetail.JobDataMap["reminderRepo"] = reminderRepo;

    DateTime evenMinuteDate = TriggerUtils.GetEvenMinuteDate(DateTime.UtcNow);


    SimpleTrigger trigger = new SimpleTrigger("TaskRemindersTrigger", null,
                        DateTime.UtcNow,
                        null,
                        SimpleTrigger.RepeatIndefinitely,
                        TimeSpan.FromMinutes(1));

    scheduler.ScheduleJob(jobDetail, trigger);
}

所以我需要像上面一样将hinterRepo传递给工作

So I need to pass in the reminderRepo into the job as I am doing above

jobDetail.JobDataMap["reminderRepo"] = reminderRepo;

这是您可以将某些东西传递给工作的唯一方法.每次执行计划后,都会重新创建一个作业,并且我假设它使用的是与我发送的相同的hinterRepo.

It's the only way you can pass something into a job. Everytime the schedule gets executed a job is recreated and I am assuming it uses the same reminderRepo that I sent in.

我在服务层中的代码再也不会执行了,当然应用程序也将启动(除非我重新部署该站点)

My code in the service layer never gets executed again and of course the application start as well(unless I redeploy the site)

工作

 public class TaskReminderJob : IJob
    {


        public void Execute(JobExecutionContext context)
        {
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            ReminderRepo reminderRepo = dataMap["reminderRepo"] as ReminderRepo;

            if (context.ScheduledFireTimeUtc.HasValue && context.NextFireTimeUtc.HasValue && reminderRepo != null)
            {
                DateTime start = context.ScheduledFireTimeUtc.Value;
                DateTime end = context.NextFireTimeUtc.Value;

                List<PersonalTaskReminder> personalTaskReminders = reminderRepo.GetPersonalTaskReminders(start, end);

                if (personalTaskReminders.Count > 0)
                {
                    reminderRepo.DeletePersonalTaskReminders(personalTaskReminders.Select(x => x.ReminderId).ToList());


                }

            }
        }

提醒回购. (当该存储库实例化时,应提供一个会话,该会话将一直持续到请求结束)

Reminder Repo. (When this repo gets instantiated a session should be given that will live till the end of the request)

  public class ReminderRepo : IReminderRepo
    {

        private readonly ISession session;

        public ReminderRepo(ISession session)
        {
            this.session = session;
        }

        public List<PersonalTaskReminder> GetPersonalTaskReminders(DateTime start, DateTime end)
        {
            List<PersonalTaskReminder> personalTaskReminders = session.Query<PersonalTaskReminder>().Where(x => x.DateToBeSent <= start && x.DateToBeSent <= end).ToList();
            return personalTaskReminders;
        }

        public void DeletePersonalTaskReminders(List<int> reminderId)
        {
            const string query = "DELETE FROM PersonalTaskReminder WHERE ReminderId IN (:reminderId)";
            session.CreateQuery(query).SetParameterList("reminderId", reminderId).ExecuteUpdate();
        }


        public void Commit()
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                transaction.Commit();
            }
        }


    }

因此,我需要某种方式使会话保持活动状态以提醒我.我所有其他回购协议的所有其他会议应该像现在一样进行.似乎只有这一个需要永远活着.

So I need some way of keeping the session alive for my reminders. All my other sessions for all my other repos should be as I have it now. It's only this one that seems to need to live forever.

修改

我每次都尝试获取一个新会话,因此我将IsessionFactory传递给了我.可能不是100%最佳,但这是我弄清楚如何进行一些新会议的唯一方法.

I tried to get a new session each time so I am passing the IsessionFactory around. Probably not 100% best but it was the only way I could figure out how to get some new sessions.

但是我不知道我的会话是否仍通过ninject关闭,因为我现在手动传递了会话.我现在在想,但无法验证.

I however do not know if my session are being closed through ninject still since I am manually passing in the session now. I thinking now but cannot verify.

 **private readonly ISessionFactory sessionFactory;**
private readonly ISchedulerFactory schedulerFactory;

public ScheduledRemindersService(ISessionFactory sessionFactory)
{
    **this.sessionFactory = sessionFactory;**
    schedulerFactory = new StdSchedulerFactory();
}

public void StartTaskRemindersSchedule()
{

    IScheduler scheduler = schedulerFactory.GetScheduler();

    scheduler.Start();

    JobDetail jobDetail = new JobDetail("TaskRemindersJob",null,typeof(TaskReminderJob));
    **jobDetail.JobDataMap["reminderRepo"] = sessionFactory;**

    DateTime evenMinuteDate = TriggerUtils.GetEvenMinuteDate(DateTime.UtcNow);


    SimpleTrigger trigger = new SimpleTrigger("TaskRemindersTrigger", null,
                        DateTime.UtcNow,
                        null,
                        SimpleTrigger.RepeatIndefinitely,
                        TimeSpan.FromMinutes(1));

    scheduler.ScheduleJob(jobDetail, trigger);
}

所以我的global.aspx是相同的,但是因为ninject现在看到"ScheduledRemindersService"现在进入了一个nhibernate会话工厂,所以它为我绑定了一个我可以使用的会话.

So my global.aspx is the same but since ninject now sees that "ScheduledRemindersService" now takes in a nhibernate session factory it binds one for me that I can use.

然后我将其传递给工作.

I then pass it off to the job.

public void Execute(JobExecutionContext context)
{
    JobDataMap dataMap = context.JobDetail.JobDataMap;
    ISessionFactory sessionFactory = dataMap["reminderRepo"] as ISessionFactory;

    if (sessionFactory != null)
    {
        ISession openSession = sessionFactory.OpenSession();
        ReminderRepo reminderRepo = new ReminderRepo(openSession);
    }
}

然后我将其传递到ReminderRepo中,因此我猜测它会忽略ninject的自动会话绑定,但我不确定100%,因此不确定会话是否已关闭.

I then pass it into my ReminderRepo so I am guessing it ignores the auto session binding from ninject but I am not 100% sure thus I am not sure if my sessions are being closed.

推荐答案

工作是否有理由不能每次运行都打开一个新会话?大概它是定期运行的,而且永远不会永远运行.

Is there a reason the job can't just open up a new session every time it runs? Presumably it's running at periodic intervals and not forever ever.

永远保持开放是遇到怪异行为的必经之路.

Keeping stuff open forever is usually a sure-fire way to encounter weird behavior.

希望这会有所帮助.

这篇关于永远保持开放状态吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆