Spring 在内存数据库中,使用hibernate并定期持久化到实际数据库
我想在hibernate中使用内存中的db,所以我的查询速度非常快。 而且,我希望定期将内存中的状态保存到一个真正的mysql数据库中。 当然,内存中的数据库应该在启动时从mysql数据库加载其初始内容。Spring 在内存数据库中,使用hibernate并定期持久化到实际数据库,spring,hibernate,in-memory-database,Spring,Hibernate,In Memory Database,我想在hibernate中使用内存中的db,所以我的查询速度非常快。 而且,我希望定期将内存中的状态保存到一个真正的mysql数据库中。 当然,内存中的数据库应该在启动时从mysql数据库加载其初始内容。 为此目的是否有良好的框架/做法?(我正在使用spring)任何教程或指针都会有所帮助 老实说,大多数像样的数据库都可以在一定程度上考虑在内存中,因为它们会缓存数据,并尽可能不频繁地访问硬盘。根据我的经验,内存中最好的数据库要么是缓存,要么是其他数据源的游戏,这些数据源已经以其他形式持久化,然后
为此目的是否有良好的框架/做法?(我正在使用spring)任何教程或指针都会有所帮助 老实说,大多数像样的数据库都可以在一定程度上考虑在内存中,因为它们会缓存数据,并尽可能不频繁地访问硬盘。根据我的经验,内存中最好的数据库要么是缓存,要么是其他数据源的游戏,这些数据源已经以其他形式持久化,然后以实时方式更新时间关键型信息,或者定期刷新非时间关键型信息 将数据从冷启动加载到内存可能是一个漫长的过程,但后续的查询将非常快 如果您试图缓存已经持久化的内容,可以查看memcache,但实际上内存中的数据库总是依赖于更持久的源,可以是MySQL、SQLServer、Cassandra、MongoDB,您可以这么说
所以有点不清楚您想要实现什么,只需说有可能从持久性数据库引入数据并拥有大量内存缓存,但您需要设计特定数据的过时程度,以及您需要多久访问一次真正的源代码以获得第二个结果。实际上,最简单的方法是使用一些核心的Hibernate功能,使用Hibernate
会话本身,并将其与第二级缓存相结合
将要缓存的实体声明为可缓存的:
@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NON_STRICT_READ_WRITE)
public class SomeReferenceData { ... }
然后,假设您使用的是JPA,执行如下定期刷新:
- 打开实体管理器
- 使用该实体管理器加载要缓存的实体,而不使用其他工具
- 保持实体管理器处于打开状态,直到下一次定期刷新,Hibernate通过脏检查机制跟踪内存中修改的SomeReferenceData的哪些实例,但不会发出任何修改查询
- 正在通过二级缓存阻止对数据库的读取
- 当需要刷新会话时,只需开始一个事务并立即提交即可李>
- Hibernate将更新数据库中已修改的实体,更新二级缓存并恢复执行
- 如果您想从数据库中重新加载所有内容,请最终关闭实体管理器并将其替换为新的实体管理器
- 否则,保持同一实体管理器处于打开状态
代码示例:
请尝试以下代码以了解总体思路:
public class PeriodicDBSynchronizeTest {
@Test
public void testSynch() {
// create the entity manager, and keep it
EntityManagerFactory factory = Persistence.createEntityManagerFactory("testModel");
EntityManager em = factory.createEntityManager();
// kept in memory due to @Cacheable
SomeReferenceData ref1 = em.find(SomeReferenceData.class, 1L);
SomeReferenceData ref2 = em.find(SomeReferenceData.class, 2L);
SomeReferenceData ref3 = em.find(SomeReferenceData.class, 3L);
....
// modification are tracked but not committed
ref1.setCode("005");
// these two lines will flush the modifications into the database
em.getTransaction().begin();
em.getTransaction().commit();
// continue using the ref data, and tracking modifications until the next request
...
}
}
尝试使用会话和二级缓存,请参见下文