【问题标题】:How can we set the Read Uncommitted isolation level with JPA and Hibernate?我们如何使用 JPA 和 Hibernate 设置 Read Uncommitted 隔离级别?
【发布时间】:2021-03-20 13:28:18
【问题描述】:

在他的名著《Java persistence with Hibernate》中,我们可以读到以下内容:

“持久化上下文是持久化实体实例的缓存......自动脏检查是这种缓存的好处之一。另一个好处是实体的可重复读取和工作单元的性能优势 -范围缓存...您无需执行任何特殊操作即可启用持久性上下文缓存。它始终处于开启状态,并且由于所示原因,无法关闭

这是否意味着使用 Hibernate 永远无法实现“读取未提交”的事务隔离级别?

【问题讨论】:

  • @Vlad Mihalcea 请问您有什么意见?

标签: java hibernate jpa isolation-level read-uncommitted


【解决方案1】:

这是否意味着使用 Hibernate 永远无法实现“读取未提交”的事务隔离级别?

不,它没有。 Hibernate 为实体提供application-level repeatable reads。这与适用于任何查询的DB-level repeatable reads 不同。

因此,如果您想要自定义隔离级别,例如 REPEATABLE_READ 用于给定事务执行的所有查询,而不仅仅是获取实体,那么您可以这样设置:

@Transactional(isolation = Isolation.REPEATABLE_READ)
public void orderProduct(Long productId) {  
    ...
}     

现在,你的问题标题是:

(如何)使用 Hibernate / JPA 实现 Read Uncommitted 隔离级别?

如果您使用的是 Oracle 和 PostgreSQL,则不能这样做,因为不支持 Read Uncommitted,而您将获得 READ_COMMITTED

对于 SQL Server 和 MySQL,设置如下:

@Transactional(isolation = Isolation.READ_UNCOMMITTED)

【讨论】:

    【解决方案2】:

    事实上,hibernate 确实通过本书中引用的一级缓存(持久性上下文)提供可重复读取

    "Transactions and concurrency control" by Vlad Mihalcea.

    如下:

    一些 ORM 框架(例如 JPA/Hibernate)提供应用程序级的可重复读取。任何检索到的实体的第一个快照都缓存在当前运行的持久性上下文中。返回相同数据库行的任何连续查询都将使用先前缓存的相同对象。这样,即使在 Read Committed 隔离级别也可以防止模糊读取。

    但是,根据上面的同一本书,似乎将 Spring 与 JPA / hibernate 一起使用允许自定义事务隔离级别。

    在上面的书中我们还可以读到以下内容:

    Spring 在使用 JpaTransactionManager 时支持事务级隔离级别。对于 JTA 事务,JtaTransactionManager 遵循 Java EE 标准并且不允许覆盖默认隔离级别。作为一种解决方法,Spring 框架提供了扩展点,因此应用程序开发人员可以自定义默认行为并实现一个 基于事务设置隔离级别的机制

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 2013-03-12
      • 2015-08-02
      相关资源
      最近更新 更多