Bha*_*r R 1 java database hibernate jpa second-level-cache
我一直在浏览有关第二级高速缓存和查询高速缓存的休眠文档,并留下了有关第二级高速缓存与数据库同步的问题,反之亦然。每个会话都可以定义自己的缓存模式,例如NORMAL,GET,PUT和REFRESH。2L缓存<->数据库同步是否会在所有情况下发生?如果是,何时会确切发生?在此先感谢。
大洋的降落
说到二级缓存,直接来
用法-指定缓存策略:事务性,读写,非严格读写或只读
就实体缓存而言,创建/更新/删除操作的预期调用顺序为:
删除:
lock(java.lang.Object, java.lang.Object)
evict(java.lang.Object)
release(java.lang.Object, org.hibernate.cache.CacheConcurrencyStrategy.SoftLock)
Run Code Online (Sandbox Code Playgroud)
更新 :
lock(java.lang.Object, java.lang.Object)
update(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)
afterUpdate(java.lang.Object, java.lang.Object, java.lang.Object,org.hibernate.cache.CacheConcurrencyStrategy.SoftLock)
Run Code Online (Sandbox Code Playgroud)
插入:
insert(java.lang.Object, java.lang.Object, java.lang.Object)
afterInsert(java.lang.Object, java.lang.Object, java.lang.Object)
Run Code Online (Sandbox Code Playgroud)
就集合缓存而言,所有修改操作实际上只会使条目无效。此处的调用顺序为:
lock(java.lang.Object, java.lang.Object)
evict(java.lang.Object)
release(java.lang.Object, org.hibernate.cache.CacheConcurrencyStrategy.SoftLock)
Run Code Online (Sandbox Code Playgroud)
Nonstrict-R / w和R / W缓存
每当会话开始时,都会向其添加时间戳。(ST)每当在缓存中加载项目时,都会向其添加时间戳。(CT)现在,如果ST <CT,则意味着会话早于缓存的项目,那么,如果我们在这个较旧的会话中查找缓存的项目,则Hibernate将不会在缓存中查找。相反,它将始终在数据库中查找,并因此以新的时间戳重新加载高速缓存中的项目。
对于非严格读写
•从来没有锁定。
•因此,当实际上在数据库中更新对象时,在提交时(直到数据库完成提交),高速缓存具有旧对象,数据库具有新对象。
•现在,如果有任何其他会话在寻找对象,它将在缓存中查找并找到旧对象。(DIRTY READ)
•但是,一旦提交完成,就会从高速缓存中逐出对象,以便下一个寻找对象的会话必须在数据库中查找。
读写
•只要有人尝试更新/删除项目,该项目就会在缓存中被软锁定,因此,如果任何其他会话试图查找它,则必须进入数据库。
•现在,一旦更新结束并且提交了数据,就可以使用新数据刷新缓存并释放锁,这样其他事务现在就可以在CACHE中查找,而不必去数据库了。
•因此,没有机会进行脏读,并且任何会话几乎都将始终从数据库/缓存中读取读已提交的数据。
总结一下:
ReadOnly cache只能读取和插入,不能执行更新/删除。性能最快。
Nonstrict Read Write Cache永远不会使用任何锁,因此总会有脏读的机会。但是,它总是从缓存中逐出该条目,以便任何后续会话始终引用DB。
Read Write cache使用锁,但以异步方式,首先在TX中进行插入/更新/删除。当缓存条目被软锁定并且其他会话必须引用数据库时。一旦TX。完成后,将释放锁并更新缓存。(在事务外部)。在某些情况下,可重复读取可能会受到影响。
Transactional caches显然,在同一事务中更新数据库和缓存,因此它相对于数据库始终处于一致状态。
Entity type大部分已更新并且具有并发读取和更新的功能,由于大多数读取将被转移到数据库,因此读写缓存策略可能不太有用。
查询缓存
需要在我们的hibernate.cfg.xml 1中启用以下属性
真正
此设置将创建两个新的缓存区域:
org.hibernate.cache.StandardQueryCache,保存缓存的查询结果
org.hibernate.cache.UpdateTimestampsCache,保存可查询表的最新更新时间戳。这些用于验证结果,因为它们是从查询缓存中提供的。
Query cache不在缓存中缓存实际实体的状态;它仅缓存标识符值和值类型的结果。因此,对于那些预期要作为查询结果缓存一部分进行缓存的实体,应始终将查询缓存与二级缓存结合使用