Hibernate가 org.hibernate를 던지는 이유는 무엇입니까?예외.잠금 획득예외?
다음 방법이 있습니다.
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"/>
Cars.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>
NB : 스레드를 추가할 때.업데이트 후 sleep(sleep), 괜찮아요.하지만 이 해결책은 깨끗하지 않습니다.
매핑에 따르면 작업 순서는 다음과 같습니다.
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);
업데이트 또는 삭제는 격리 레벨에서도 배타적 잠금을 획득하는 것을 의미합니다.
다른 트랜잭션이 현재 실행 중인 트랜잭션(문제의 행을 이미 잠근 경우)과 동일한 행을 업데이트하려는 경우 교착 상태가 아니라 잠금 획득 시간 초과 예외가 발생합니다.
교착 상태에 빠졌기 때문에 여러 테이블에서 잠금을 획득하고 잠금 획득 순서가 제대로 지정되지 않았음을 의미합니다.
따라서 서비스 계층 메소드가 DAO 메소드가 아닌 트랜잭션 경계를 설정해야 합니다.지원되는 메소드를 사용하기 위해 Get and Find Methods를 선언했습니다. 즉, 현재 트랜잭션이 시작된 경우에만 트랜잭션을 사용합니다.이 경우에도 필수 항목을 사용해야 하지만 다음과 같이 간단히 표시해야 합니다.read-only = true
.
따라서 트랜잭션 측면에서 DAO가 아닌 "mymethod"에 트랜잭션 경계를 적용해야 합니다.
저는 자동차 -> (1 -n) 장소가 있습니다.그리고 테이블 플레이스(id_car)에 외국인 키가 있습니다.이 외래 키에는 색인이 없습니다.이 외래 키에 인덱스를 추가하면 문제가 해결됩니다.
언급URL : https://stackoverflow.com/questions/25097957/why-does-hibernate-throw-org-hibernate-exception-lockacquisitionexception
'programing' 카테고리의 다른 글
파이썬을 사용하는 모든 ASCII 문자 목록을 가져오려면 어떻게 해야 합니까? (0) | 2023.07.22 |
---|---|
TestRestTemplate 사용 시 예외 발생 (0) | 2023.07.22 |
Git는 왜 이 텍스트 파일을 이진 파일로 취급합니까? (0) | 2023.07.22 |
응용 프로그램 인수를 기반으로 실행할 스프링 배치 작업 선택 방법 - 스프링 부트 Java 구성 (0) | 2023.07.22 |
docker-compose의 env-file 및 MariaDB (0) | 2023.07.22 |