Występuje błąd Oracle Deadlock (org.hibernate.util.JDBCExceptionReporter - ORA-00060: zakleszczenie wykryte podczas oczekiwania na zasoby). Sugerowano, że problem dotyczy procesu, który wykonuje operacje tylko do odczytu przy użyciu Hibernuj, podczas gdy inny proces wykonuje aktualizację w tym samym wierszu.Zakleszczenie Oracle, gdy aplikacja Hibernate ładuje dane do użycia tylko raz.
Proces typu "tylko do odczytu" jest konfigurowany przy użyciu trybu hibernacji i wiosny. Nie zdefiniowaliśmy jawnie transakcji dla usługi. Chociaż może to nie być idealne - nie widzę powodu, dla którego Hibernate spróbuje uzyskać wyłączną blokadę w wierszu, gdy nie są wykonywane operacje zapisu/aktualizacji - tylko get/load.
Moje pytanie brzmi: Czy w trybie hibernacji, gdy nie zdefiniowano jawnego zarządzania transakcjami, spróbuj uzyskać blokadę odczytu/zapisu w wierszu, nawet jeśli wykonywane jest tylko "obciążenie" obiektu. Nie wykonano zapisu/aktualizacji.
Czy jest możliwe, że zdefiniowanie transakcji wokół usługi, która ładuje dane, a następnie konkretne POWIADOMIENIE w atrybucie transakcji spowoduje, że Hibernate zignoruje istniejącą blokadę wiersza i po prostu załaduje dane do celów tylko do odczytu?
Oto niektóre przykłady kodu:
do załadunku rekord używamy HibernateDaoTemplate
public class HibernatePurchaseOrderDataService extends HibernateDaoSupport implements PurchaseOrderDataService {
public PurchaseOrderData retrieveById(Long id) {
return (PurchaseOrderData)getHibernateTemplate().get(PurchaseOrderData.class, id);
}
}
Konfiguracja Wiosna za usługę Wywołanie tej metody jest:
<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>
Rzeczywisty zakleszczenie występuje na jednym z rekordów PurchaseOrderItem ładowanych przez wywołanie do obciążenia PurchaseOrder.
Czy spowodowałoby to zakleszczenie, jeśli ładowany rekord został zablokowany przez inny proces? A jeśli tak - czy dodanie opakowania transakcji, takiego jak poniżej, rozwiązałoby problem?
<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>
Aktualizacja: Zespół DataBase odnotowano śladowe wiadomości na serwerze, które wydają się wskazywać, że nasz „tylko do odczytu” proces jest faktycznie automatycznie piśmie do bazy danych. Są zarejestrowane polecenia "UPDATE", które są wykonywane na dokładnych kolumnach, które odczytujemy z bazy danych. Wygląda na to, że Hibernate automatycznie zapisuje te rekordy z powrotem do bazy danych (nawet jeśli nie prosimy o to). To prawdopodobnie tłumaczyłoby, dlaczego istnieje impas.
Czy przyczyną może być SUMA PŁUKANIA lub coś podobnego? Wygląda bardziej na to, że rozwiązaniem może być wykorzystanie opakowania transakcji z readOnly na nim ...
To nie jest dokładnie to, co się działo - ale wydawało się podobne. Wartości nie zostały "ustawione" w kodzie. Hibernate próbował z jakiegoś powodu przywrócić te same dane (dane w DB nigdy nie zostały zaktualizowane do różnych wartości). – jonathanq