Oracle Deadlock (ORA-00060 : 리소스를 기다리는 동안 교착 상태가 감지되었습니다.) 오류가 발생했습니다. 이 문제는 다른 프로세스가 같은 행에서 업데이트를 수행하는 동안 Hibernate를 사용하여 읽기 전용 연산을 수행하는 프로세스에서 발생한다고 제안되었습니다.Hibernate 응용 프로그램이 읽기 전용으로 데이터를로드 할 때 교착 상태가 발생했습니다.
해당 읽기 전용 프로세스는 최대 절전 모드와 봄 모드를 사용하여 구성됩니다. 우리는 서비스에 대한 트랜잭션을 명시 적으로 정의하지 않았습니다. 그 동안 이상하지 않을 수 있습니다 - 저장/업데이트 작업이 수행되지 않을 때 Hibernate가 행에 독점적 인 잠금을 얻으려고하는 이유를 알지 못합니다 - get/load 만.
제 질문은 : 명시 적 트랜잭션 관리가 정의되어 있지 않을 때 Hibernate는 객체의 "로드"만 수행되는 경우에도 행에 읽기/쓰기 잠금을 시도하려고합니까? 저장/업데이트가 수행되지 않습니다.
데이터를로드하는 서비스를 중심으로 트랜잭션을 정의한 다음 transactionAttributes에 READONLY를 명시하면 Hibernate가 이미 존재하는 행 잠금을 무시하고 읽기 전용으로 데이터를로드 할 수 있습니까? 여기
는 일부 코드의 예입니다 : 우리가 HibernateDaoTemplate을 사용하고있는 기록을로드하기위한
public class HibernatePurchaseOrderDataService extends HibernateDaoSupport implements PurchaseOrderDataService {
public PurchaseOrderData retrieveById(Long id) {
return (PurchaseOrderData)getHibernateTemplate().get(PurchaseOrderData.class, id);
}
}
이 메서드를 호출 서비스에 대한 봄의 구성은 다음과 같습니다
<bean id="orderDataService"
class="com.example.orderdata.HibernatePurchaseOrderDataService">
<property name="sessionFactory" ref="orderDataSessionFactory"/>
</bean>
<bean id="orderDataSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="hibernateDataSource"/>
<property name="hibernateProperties" ref="hibernateProperties"/>
<property name="mappingResources">
<list>
<value>com/example/orderdata/PurchaseOrderData.hbm.xml</value>
<value>com/example/orderdata/PurchaseOrderItem.hbm.xml</value>
</list>
</property>
</bean>
실제에게 PurchaseOrder로드에 대한 호출에 의해로드 된 PurchaseOrderItem 레코드 중 하나에서 교착 상태가 발생합니다.
로드중인 레코드가 다른 프로세스에 의해 잠긴 경우 교착 상태가 발생합니까? 그렇다면 아래의 트랜잭션 래퍼를 추가하면 문제가 해결됩니까?
<bean id="txWrappedOrderDataService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="orderDataService"/>
<property name="transactionAttributes">
<props>
<!-- all methods require a transaction -->
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
업데이트 : 데이터베이스 팀은 "읽기 전용"프로세스가 실제로 자동으로 데이터베이스에 기록되어 있음을 시사한다 서버에서 추적 메시지를 볼 수있다. 데이터베이스에서 읽는 정확한 열에서 수행되는 "UPDATE"명령이 기록됩니다. Hibernate가 자동적으로이 레코드들을 데이터베이스에 다시 쓰고있는 것처럼 보인다. (우리가 요청하지는 않지만). 그러면 교착 상태가 발생하는 이유를 설명 할 수 있습니다.
세션 플러시 또는 이와 유사한 이유로 인해 발생할 수 있습니까? 솔루션처럼 readOnly를 사용하여 트랜잭션 래퍼를 사용할 수도 있습니다 ...
정확히 무슨 일이 일어나고있는 것은 아니지만 비슷한 것처럼 보입니다. 값은 코드에서 "설정"되지 않았습니다. Hibernate는 실제로 어떤 이유로 DB에있는 데이터가 결코 다른 값으로 업데이트되지 않도록 동일한 데이터를 다시 쓰려고 시도했다. – jonathanq