在他的名著《Java persistence with Hibernate》中,我们可以读到以下内容:
“持久性上下文是持久性实体实例的缓存......自动脏检查是这种缓存的好处之一。另一个好处是实体的可重复读取和工作范围缓存单元的性能优势......你不需要做任何特别的事情来启用持久性上下文缓存。它总是打开的,并且由于所示的原因,不能被关闭。
这是否意味着使用 Hibernate 永远无法实现“读取未提交”的事务隔离级别?
在他的名著《Java persistence with Hibernate》中,我们可以读到以下内容:
“持久性上下文是持久性实体实例的缓存......自动脏检查是这种缓存的好处之一。另一个好处是实体的可重复读取和工作范围缓存单元的性能优势......你不需要做任何特别的事情来启用持久性上下文缓存。它总是打开的,并且由于所示的原因,不能被关闭。
这是否意味着使用 Hibernate 永远无法实现“读取未提交”的事务隔离级别?
这是否意味着使用 Hibernate 永远无法实现“读取未提交”的事务隔离级别?
不,它没有。Hibernateapplication-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)
实际上,hibernate 确实通过本书中引用的一级缓存(持久性上下文)提供了可重复读取
如下:
一些 ORM 框架(例如 JPA/Hibernate)提供应用程序级的可重复读取。任何检索到的实体的第一个快照都缓存在当前运行的持久性上下文中。返回相同数据库行的任何连续查询都将使用先前缓存的相同对象。这样,即使在 Read Committed 隔离级别也可以防止模糊读取。
但是,根据上面的同一本书,似乎将 Spring 与 JPA / hibernate 一起使用允许自定义事务隔离级别。
在上面的书中,我们还可以阅读以下内容:
Spring 在使用 JpaTransactionManager 时支持事务级隔离级别。对于 JTA 事务,JtaTransactionManager 遵循 Java EE 标准并且不允许覆盖默认隔离级别。作为一种变通方法,Spring 框架提供了扩展点,因此应用程序开发人员可以自定义默认行为并实现一种机制以基于事务设置隔离级别。