- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我已经为 NHibernate(使用 NHibernate.Linq 和 Fluent NHibernate )设置了查询缓存。一切正常,直到我执行 session.Save(new Widget())
(即 SQL INSERT
)。在那之后,对该类型 Widget
的所有查询都会错过查询缓存。对其他实体类型的查询被缓存得很好。
using (ISession session = MySessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
// this INSERT screws things up
var widget = new Widget {Name = "Foo"};
session.Save(widget);
var query = (from w in session.Query<Widget>().Cacheable()
where w.Name == "Bar"
select w);
var fetched1 = query.FirstOrDefault();
var fetched2 = query.FirstOrDefault(); // miss?!
transaction.Commit();
}
}
如果我开始一个新的 Transaction
,问题仍然存在。如果我开始一个新的 Session
,问题就会消失。这似乎有点奇怪,因为我的理解是二级缓 stub 据 SessionFactory
(而不是 Session
)重置。
我认为这不重要,但我正在使用 HashtableCacheProvider
,因为我现在只是在测试。
最佳答案
您描述的行为是正确的( more here )。
The update timestamp cache is not updated until you commit the transaction! This is to ensure that you will not read "uncommitted values" from the cache.
每当我们在缓存中获得的 type
发生变化时——缓存的数据都是陈旧的……直到提交完整的事务。
假设您已缓存此过滤器的结果:
var query = (from w in session.Query<Widget>().Cacheable()
where w.Name == "B*" // all names starting with B
select w);
稍后将添加新的 Widget:
var widget = new Widget {Name = "Brigitte"};
session.Save(widget);
// explicit Flush is not needed,
// but then, until Commit(), query will never return Brigitte
session.Flush(); // to immediately execute INSERT
如果查询仍然被缓存,Brigitte 将永远不会出现......
而在事务中,使用 FirstOrDefault() 的查询会立即执行 - 写操作可以等待提交时刷新。
因为事务,所有包含的操作(插入、更新、选择)都不能从缓存中获利,因为只有作为批处理的事务才有意义。因此,在调用 commit 之前,无法使用缓存。
许多详细且非常有用的信息可以在这里找到:First and Second Level caching in NHibernate
The timestamp cache is updated whenever a table is written to, but in a tricky sort of way:
- When we perform the actual writing, we write a value that is somewhere in the future to the cache. So all queries that hit the cache now will not find it, and then hit the DB to get the new data. Since we are in the middle of transaction, they would wait until we finish the transaction. If we are using low isolation level, and another thread / machine attempts to put the old results back in the cache, it wouldn't hold, because the update timestamp is into the future.
- When we perform the commit on the transaction, we update the timestamp cache with the current value.
关于c# - NHibernate - 查询在保存新实体后错过了查询缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14299456/
我无法在附加行中显示“真”、“假”、"is"和“否”按钮。 我在这里有一个应用程序:Application 请按照以下步骤使用应用程序: 1。当你打开应用程序时,你会看到一个绿色的加号按钮,点击 在此
我是一名优秀的程序员,十分优秀!