如何让NHibernate在数据库停机时幸存?

时间:2011-02-13 02:17:28

标签: c# nhibernate

我有一个C#控制台应用程序,我想继续运行,即使它的数据库崩溃。在这种情况下,它应该轮询数据库以查看它何时重新联机,然后恢复操作。我有这个代码,我不喜欢:

    public static T Robust<T>(Func<T> function)
    {
        while (true)
        {
            try
            {
                return function();
            }
            catch (GenericADOException e)
            {
                Console.WriteLine("SQL Exception. Retrying in 10 seconds");
                Thread.Sleep(10000);
            }
        }
    }
    [...]
    N.Robust(() => Session.CreateCriteria(typeof(MyEntity)).List());

问题是我必须在任何地方插入那个令人讨厌的N.Robust构造,这会使代码变得混乱。此外,我冒着忘记它的风险。我一直在研究使用NHibernate的EventListeners或Inceptors,但还是无法使它工作。我真的需要使用NHibernate来实现这个功能吗?

更新 好吧,所以我已经克服了我的两个问题之一。通过注入我自己的事件监听器,我至少可以确保对数据库的所有调用都通过上述方法。

        _configuration.EventListeners.LoadEventListeners
         = new ILoadEventListener[] { new RobustEventListener() };
        [...]
        public class RobustEventListener : ILoadEventListener
        {
            public void OnLoad(LoadEvent e, LoadType type)
            {
                if (!RobustMode)
                    throw new ApplicationException("Not allowed");
            }
        }

我仍然有一个杂乱的代码库,但我认为为增加服务正常运行时间付出代价是合理的价格。

1 个答案:

答案 0 :(得分:5)

容忍数据库停机的一种archtecturial方法是使用队列(客户端和/或服务器端)。对于静态或大部分静态数据的读取,在客户端缓存一个到期窗口(比如说15到30分钟)。

如果您有复杂的数据库事务,这是非常重要的。

像你提议的那样睡觉,很少是个好主意。

另一个选项(主要用于偶尔连接的应用程序)是使用数据库复制。使用具有复制支持的RDBMS(例如,Sql Server),让您的应用程序始终与本地数据库通信,并让复制引擎在连接启动时自动处理与远程数据库的同步。这可能会引入冲突管理/解决问题。

相关问题