Возникла ошибка Oracle Deadlock (org.hibernate.util.JDBCExceptionReporter - ORA-00060: обнаружена тупиковая ситуация при ожидании ресурса). Предполагается, что проблема связана с процессом, который выполняет операции только для чтения, используя Hibernate, в то время как другой процесс выполняет обновление в той же строке.
Процесс, доступный только для чтения, настраивается с использованием Hibernate и Spring. Мы явно не определили транзакцию для сервиса. Хотя это может и не быть идеальным - я не понимаю, почему Hibernate пытается установить монопольную блокировку строки, когда не выполняются операции сохранения / обновления - только получение / загрузка.
Итак, мой вопрос: пытается ли Hibernate, когда не определено явное управление транзакциями, получить блокировку чтения / записи для строки, даже если выполняется только «загрузка» объекта. Сохранение / обновление не выполняется.
Возможно ли, что определение транзакции вокруг службы, которая загружает данные, а затем, в частности, произнесение READONLY для транзакции атрибутов, приведет к тому, что Hibernate проигнорирует уже существующую блокировку строки и просто загрузит данные только для чтения?
Вот несколько примеров кода:
Для загрузки записи мы используем HibernateDaoTemplate
public class HibernatePurchaseOrderDataService extends HibernateDaoSupport implements PurchaseOrderDataService {
public PurchaseOrderData retrieveById(Long id) {
return (PurchaseOrderData)getHibernateTemplate().get(PurchaseOrderData.class, id);
}
}
Конфигурация Spring для службы, вызывающей этот метод:
<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>
Фактическая тупиковая ситуация возникает в одной из записей PurchaseOrderItem, загружаемых при вызове загрузки PurchaseOrder.
Приведет ли это к взаимоблокировке, если загружаемая запись была заблокирована другим процессом? И если это так - решит ли проблема добавление оболочки транзакций, такой как приведенная ниже?
<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>
Обновление: команда DataBase увидела на сервере сообщения трассировки, которые, кажется, указывают на то, что наш процесс «только для чтения» фактически выполняет запись в базу данных автоматически. В журнале есть команды «ОБНОВИТЬ», которые выполняются для тех столбцов, которые мы читаем из базы данных. Похоже, что Hibernate автоматически записывает эти записи обратно в базу данных (хотя мы этого не просим). Это, вероятно, объясняет, почему существует тупик.
Может ли это быть из-за Сеансовой FLUSH или чего-то подобного? Больше похоже на то, что решение может заключаться в использовании оболочки транзакций с readOnly на нем ...