gpt4 book ai didi

java - 为什么 Hibernate 会抛出 org.hibernate.exception.LockAcquisitionException?

转载 作者:IT老高 更新时间:2023-10-28 13:46:58 30 4
gpt4 key购买 nike

我有这个方法:

mymethod(long id){  
Person p = DAO.findPerson(id);

Car car = new Car();
car.setPerson(p);
p.getCars().add(car);

DAO.saveOrUpdate(car);
DAO.saveOrUpdate(p);
DAO.delete(p.getCars().get(0));//A person have many cars
}

映射:

Person.hbm.xml

<!-- one-to-many : [1,1]-> [0,n] -->
<set name="car" table="cars" lazy="true" inverse="true">
<key column="id_doc" />
<one-to-many class="Car" />
</set>

<many-to-one name="officialCar"
class="Car"
column="officialcar_id" lazy="false"/>

汽车.hbm.xml

<many-to-one name="person" class="Person"
column="id_person" not-null="true" lazy="false"/>

此方法适用于单个线程,但在多个线程上,给我一个错误:

02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - WARN - org.hibernate.util.JDBCExceptionReporter - SQL Error: 60, SQLState: 61000 
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - ERROR - org.hibernate.util.JDBCExceptionReporter - ORA-00060: deadlock detection while waiting for a resource
 
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - WARN - org.hibernate.util.JDBCExceptionReporter - SQL Error: 60, SQLState: 61000
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - ERROR - org.hibernate.util.JDBCExceptionReporter - ORA-00060: deadlock detection while waiting for a resource
 
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - ERROR - org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.LockAcquisitionException: Could not execute JDBC batch update

AOP 事务:

<tx:advice id="txAdviceNomService" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
<tx:method name="getAll*" read-only="true" propagation="SUPPORTS" />
<tx:method name="find*" read-only="true" propagation="SUPPORTS" />
</tx:attributes>
</tx:advice>

注意:当我在更新后添加 Thread.sleep(5000) 时,没关系。但是这个解决方案并不干净。

最佳答案

根据您的映射,操作顺序应如下所示:

Person p = DAO.findPerson(id);

Car car = new Car();
car.setPerson(p);

DAO.saveOrUpdate(car);

p.getCars().add(car);

Car firstCar = p.getCars().get(0);
firstCar.setPerson(null);
p.getCars().remove(firstCar);
if (p.officialCar.equals(firstCar)) {
p.officialCar = null;
p.officialCar.person = null;
}

DAO.delete(firstCar);

更新删除意味着获取独占锁,即使在READ_COMMITTED上也是如此。隔离级别。

如果另一个事务想要用当前正在运行的事务(已经锁定该行)更新同一行,您将不会遇到死锁,但会出现锁获取超时异常。

由于你遇到了死锁,这意味着你在多个表上获取了锁,并且锁获取的顺序不正确。

因此,请确保服务层方法设置事务边界,而不是 DAO 方法。我看到您声明了使用 SUPPORTED 的 getfind 方法,这意味着它们仅在当前启动时才会使用事务。我认为您也应该对这些使用 REQUIRED,但只需将它们标记为 read-only = true

因此,请确保事务方面将事务边界应用于“mymethod”而不是 DAO 。

关于java - 为什么 Hibernate 会抛出 org.hibernate.exception.LockAcquisitionException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25097957/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com