我使用SysCache2作为NHibernate的第二级缓存提供程序。这是测试代码:
`ISession session = NHibernateHelper.GetSession();
Model.Task t1 = session.Get<Model.Task>("e84wqbarscj5");
richTextBox1.AppendText(t1.BuyerAccount.BuyerName);
session.Close();`
第一次运行测试代码,控制台显示NHibernate执行了两次SQL查询。控制台第二次运行测试代码,显示NHibernate尚未执行任何SQL查询。而且我认为这表明二级缓存正常工作。
接下来,我在Web服务中执行类似的代码,这是代码:
`AppServiceGetTaskResponse result = new AppServiceGetTaskResponse();
ISession hSession = NHibernateHelper.GetSession();
Model.Task task = hSession.Get<Model.Task>(request.TaskId);
result.BuyerName = task.BuyerAccount.BuyerName;
hSession.Close();
retrun result;`
我第一次使用Http客户端访问此Web服务,控制台显示NHibernate执行了两次SQL查询。这可以。我第二次使用相同的客户端访问Web服务,但是这次第二级缓存未按预期工作。控制台显示NHibernate再次执行了两次SQL查询。
我进行了新的尝试,并如下修改了代码:
`AppServiceGetTaskResponse result = new AppServiceGetTaskResponse();
ISession hSession = NHibernateHelper.GetSession();
Model.Task task = hSession.Get<Model.Task>(request.TaskId);
result.BuyerName = task.BuyerAccount.BuyerName;
hSession.Close();
if (result.BuyerName != "")
{
hSession = NHibernateHelper.GetSession();
task = hSession.Get<Model.Task>(request.TaskId);
result.BuyerName = task.BuyerAccount.BuyerName;
hSession.Close();
}
retrun result;`
我使用相同的客户端来访问修改后的Web服务。这次控制台显示NHibernate执行了2个sql查询。二级缓存似乎可以再次使用。
最后,我在log4net中添加了调试日志,发现NHibernate自动清除了所有第二级缓存。因为如果在正常的测试程序中运行相同的代码,则不会执行自动清除,因此我想它与Web服务或会话内容的线程管理有关。
`NHibernate.Impl.SessionFactoryImpl: 2020-02-28 13:17:01,185 DEBUG evicting second-level cache for: Model.BuyerAccount
NHibernate.Impl.SessionFactoryImpl: 2020-02-28 13:17:01,185 DEBUG evicting second-level cache for: Model.Buyer`
第二级缓存保持在SessionFactory
级别。理想情况下,应仅针对应用程序范围/生命周期构建一次。这非常适合您的第一个示例(测试应用程序)。
[在第二个示例(Web服务)中,我想这已经崩溃了。我怀疑您的SessionFactory
被销毁并再次创建。这就是为什么在销毁第一个请求时维护的第二级缓存,并且对于第二个调用,它导致再次执行两个查询以构建新的缓存。
我怀疑问题出在您的NHibernateHelper
类和SessionFactory
的范围内。
我自己解决了这个问题。在Web服务中,有一种写日志的方法被执行,它使用执行本机SQL的方法:session.CreateSQLQuery(“ insert into ...”),这使NHibernate在2-上自动执行逐出操作。级缓存。我改用session.save()方法,此问题已解决。但是我不懂这个原理,有人可以帮我回答吗?