【发布时间】:2018-05-16 18:00:10
【问题描述】:
我试图了解 READ COMMITED 和 READ UNCOMMITED 隔离级别在 Hibernate 中的工作方式,需要一些解释。
有 2 个线程 THR1 和 THR2 都执行相同的事务方法(Spring Transactional 注释,隔离级别设置为 READ COMMITED)。相应地将创建的事务命名为这些线程 TRA1 和 TRA2。事务方法如下所示:
public void updateOrSavePreference(String name, String value) {
Preference preferenceToUpdate = findPreferenceUsingNamedQuery(name); // line 1. shared read lock acquired (uses HibernateTemplate.findByNamedQueryAndNamedParam(...))
if (preferenceToUpdate != null) { // line 2.
preferenceToUpdate.setValue(value); // line 3. exclusive write lock acquired (actually I use the HibernateTemplate.merge(...) method
// instead a setter because the entity type is immutable, but it seems irrelevant for this example)
} else { // line 4.
HibernateTemplate.save(preferenceToUpdate); // line 5. exclusive write lock acquired
}
}
Preference 类使用 Entity(optimisticLock = OptimisticLockType.NONE) 进行注释,以强制执行该实体的 2PL 模型(我错了吗?)。我使用 Oracle 数据库。
考虑以下场景:
假设线程 THR1 进入第 1 行并查询一个对象。如果我理解正确,该线程创建的事务 TRA1 会为查询的条目获取共享读锁。那么,如果 THR2 线程跳到第 3 行试图获取该实体的独占写锁,那么在 TRA1 释放读锁之前是否不应该阻塞 THR2?
假设线程 THR1 进入第 3 行并获取实体的独占写入锁(独占锁一直保持到 TRA1 transaction completes)。然后,THR2 线程进入第 1 行并尝试查询该实体。不应该阻塞 THR2,因为 TRA2 事务试图获取读锁,而其他事务 TRA1 持有该实体的排他写锁?
如果我从第 2 点为 READ UNCOMMITED 隔离级别重现场景,则执行 TRA2 事务的 THR2 不会看到 THR1 在 TRA1 事务中所做的更改,即使在 refreshing 或再次查询实体之后 ("评估表达式”在调试下)。为什么?
【问题讨论】:
标签: java spring hibernate transactions isolation-level