Hibernate - Pessimistic_Write LockMode在Oracle DB

时间:2016-12-24 19:16:25

标签: oracle hibernate

Hibernate 4.2 Pessimistic_Write在使用PostgreSQL和Microsoft SQL Server时,Oracle DB中的锁定表现不正常,它按预期工作。 有什么想法吗?

让我提出更多解释。

我在日志中收到StaleObjectException

  

StaleObjectException: - "行被另一个更新或删除   事务(或未保存的值映射不正确)hibernate"

Hibernate无法在Oracle DB上保存Pessimistic_Write LockMode,但在其他数据库中它运行正常。这是在并发模式(多线程环境)

中访问的

代码: -

private static final String query1= "select e from EMPLOYEE e join e.addressList address where address in (:addressList) order by e.streetName,e.createdOn";

Query query = getSession().createQuery(query1).setLockOptions(new LockOptions(LockMode.PESSIMISTIC_WRITE));

1 个答案:

答案 0 :(得分:1)

问题在于Hibernate如何处理Oracle中的悲观写锁。 每当执行悲观锁定以锁定行时,其他数据库将触发单个查询以获取行并锁定该行,以便其他用户无法修改加载的记录。处理方式不同 在Oracle的情况下通过Hibernate。在Oracle的情况下,它首先使用“SELECT FOR UPDATE”子句查询一个用于加载记录,另一个用于锁定已加载的记录。现在的问题是Hibernate for Oracle生成的两个sql语句 不是原子的并且由锁控制,因此在内部我们触发的单个查询转换为两个查询。由于这两个查询不是原子的,如果两个线程触发了我们的查询,那么这两个查询都会加载相同的记录而不会锁定。 在此之后,第一个线程获取锁(第二个线程已经加载)并更新它。现在,当第二个线程尝试获取已加载的记录的锁时,它会检测到更改,因为第一个线程已更新它,因此 引发陈旧对象异常。由于这是核心Hibernate平台的问题,我们无法解决此缺陷的根本原因。

我们找到了一个解决方法。为了解决这个问题,我们引入了一个解决方法,在触发实际查询之前通过Pessimistic write锁定另一个表。这将确保线程锁定行为正常工作,代价是响应时间略有增加(几毫秒)。