-1

I use SysCache2 as the second-level cache provider for NHibernate. Here is the test code:

`ISession session = NHibernateHelper.GetSession();
Model.Task t1 = session.Get<Model.Task>("e84wqbarscj5");
richTextBox1.AppendText(t1.BuyerAccount.BuyerName);
session.Close();`

Running the test code for the first time, the console shows that NHibernate executed the sql query twice. Running the test code for the second time, the console shows that NHibernate has not executed any SQL queries. And I think it indicates that the second-level cache is working properly.

Next, I execute similar code in a web service, Here is the code:

`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;`

I use an Http client to access this web service for the first time, the console shows that NHibernate executed the sql query twice. This is fine. I used the same client to access the web service for the second time, but this time the second-level cache did not work as expected. The console shows that NHibernate executed the sql query twice again.

I made a new attempt and modified the code as follows:

`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;`

I used the same client to access the modified web service. This time the console showed that NHibernate executed 2 sql queries. The second-level cache seemed to work again.

Finally, I added debug log with log4net and found that NHibernate automatically cleared all the second-level caches. Because if the same code runs in a normal test program, no automatic cleanup will be performed, so I guess it is related to the thread management of web service or session content.

`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`

1 Answers1

0

I solved the problem myself. In the web service, there is a method to write log is executed, it uses the method of executing native SQL: session.CreateSQLQuery("insert into ..."), which causes NHibernate to automatically perform an evict operation on the 2-level cache. I use the session.save() method instead, the problem is resolved. But I don't understand the principle, can anyone help me answer it?

  • When you issue a DML command directly to the database, Nhibernate can no longer ensure cached data consistency. In this case nhibernate will throw away all cached data by considering it invalid. If you are making use of L2 cache, make sure not to use raw SQL queries for Insert/update/delete. You can use the session.CreateQuery instead which uses the HQL and can understand the changes to update cached data. – Mazhar Qayyum Jul 27 '22 at 17:01