海洋公园网站建设方案,seo效果分析,什么网站可以查建设用地规划许可证,网站模板中文乱码介绍 在我以前的文章中#xff0c;我描述了应用程序级事务如何为长时间的对话提供合适的并发控制机制。 所有实体都在Hibernate会话的上下文中加载#xff0c;充当事务后写式缓存 。 Hibernate持久性上下文可以包含给定实体的一个引用和一个引用。 一级缓存可确保会话级可重… 介绍 在我以前的文章中我描述了应用程序级事务如何为长时间的对话提供合适的并发控制机制。 所有实体都在Hibernate会话的上下文中加载充当事务后写式缓存 。 Hibernate持久性上下文可以包含给定实体的一个引用和一个引用。 一级缓存可确保会话级可重复读取。 如果对话跨越多个请求我们可以进行应用程序级的可重复读取。 长时间的对话本质上是有状态的因此我们可以选择分离的对象或长期的持久性上下文 。 但是应用程序级可重复读取需要应用程序级并发控制策略例如乐观锁定。 抓住 但是这种行为有时可能被证明是出乎意料的。 如果您的Hibernate会话已经加载了给定的实体那么任何后续的实体查询JPQL / HQL都将返回完全相同的对象引用不考虑当前加载的数据库快照 在此示例中我们可以看到第一级缓存可防止覆盖已加载的实体。 为了证明这种行为我提出了以下测试案例 final ExecutorService executorService Executors.newSingleThreadExecutor();doInTransaction(new TransactionCallableVoid() {Overridepublic Void execute(Session session) {Product product new Product();product.setId(1L);product.setQuantity(7L);session.persist(product);return null;}
});doInTransaction(new TransactionCallableVoid() {Overridepublic Void execute(Session session) {final Product product (Product) session.get(Product.class, 1L);try {executorService.submit(new CallableVoid() {Overridepublic Void call() throws Exception {return doInTransaction(new TransactionCallableVoid() {Overridepublic Void execute(Session _session) {Product otherThreadProduct (Product) _session.get(Product.class, 1L);assertNotSame(product, otherThreadProduct);otherThreadProduct.setQuantity(6L);return null;}});}}).get();Product reloadedProduct (Product) session.createQuery(from Product).uniqueResult();assertEquals(7L, reloadedProduct.getQuantity());assertEquals(6L, ((Number) session.createSQLQuery(select quantity from Product where id :id).setParameter(id, product.getId()).uniqueResult()).longValue());} catch (Exception e) {fail(e.getMessage());}return null;}
}); 该测试案例清楚地说明了实体查询和SQL预测之间的区别。 尽管SQL查询投影总是加载最新的数据库状态但是实体查询结果由第一级缓存管理以确保会话级可重复读取。 解决方法1如果您的用例要求重新加载最新的数据库实体状态则只需刷新有问题的实体。 解决方法2如果希望将某个实体与Hibernate一级缓存解除关联则可以轻松地将其退出 因此下一个实体查询可以使用最新的数据库实体值。 超越偏见 休眠是一种手段而不是目标。 数据访问层既需要读取又需要写入而普通的JDBC和Hibernate都不是一种千篇一律的解决方案。 数据知识堆栈更适合于获取最多的数据读取查询和写入DML语句。 尽管原生SQL仍然是事实上的关系数据读取技术但是Hibernate在写入数据方面表现出色。 Hibernate是一个持久性框架您永远不要忘记这一点。 如果计划将更改传播回数据库则加载实体是有意义的。 您不需要加载用于显示只读视图的实体在这种情况下SQL投影是更好的选择。 会话级可重复读取可防止并发写入场景中的更新丢失因此有充分的理由说明实体不会自动刷新。 也许我们选择了手动刷新脏属性 并且自动刷新实体可能会覆盖同步的未决更改。 设计数据访问模式并不是一件容易的事值得投资坚实的集成测试基础。为避免任何未知行为我强烈建议您验证所有自动生成的SQL语句以证明其有效性和效率 。 代码可在GitHub上获得 。 翻译自: https://www.javacodegeeks.com/2014/10/hibernate-application-level-repeatable-reads.html