我有一个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());
Run Code Online (Sandbox Code Playgroud)
问题是我必须在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");
}
}
Run Code Online (Sandbox Code Playgroud)
我仍然有一个杂乱的代码库,但我认为这是一个合理的价格,以支付增加服务正常运行时间.
容忍数据库停机的一种archtecturial方法是使用队列(客户端和/或服务器端).对于静态或大部分静态数据的读取,在客户端缓存具有到期窗口(例如15-30分钟).
如果您有复杂的数据库事务,这是非常重要的.
像你提议的那样睡觉,很少是一个好主意.
另一个选项(主要用于偶尔连接的应用程序)是使用数据库复制.使用具有复制支持的RDBMS(例如,Sql Server),让您的应用程序始终与本地数据库通信,并让复制引擎在连接启动时自动处理与远程数据库的同步.这可能会引入冲突管理/解决问题.