हम ओरेकल डेडलॉक (org.hibernate.util.JDBCExceptionReporter - ORA-00060: संसाधन की प्रतीक्षा करते समय मृतक का पता चला) त्रुटि का सामना कर रहे हैं। यह सुझाव दिया गया है कि यह मुद्दा एक प्रक्रिया के साथ है जो हाइबरनेट का उपयोग करके पठनीय संचालन कर रहा है जबकि एक और प्रक्रिया एक ही पंक्ति पर एक अद्यतन कर रही है।ओरेकल डेडलॉक जब रीडोनली उपयोग के लिए अनुप्रयोग लोडिंग डेटा को हाइबरनेट करें
प्रश्न में केवल पढ़ने की प्रक्रिया हाइबरनेट और वसंत का उपयोग करके कॉन्फ़िगर की गई है। हमने सेवा के लिए लेनदेन को स्पष्ट रूप से परिभाषित नहीं किया है। हालांकि यह आदर्श नहीं हो सकता है - मैं यह देखने में असफल रहा कि क्यों हाइबरनेट एक पंक्ति पर एक विशेष लॉक प्राप्त करने का प्रयास करेगा जब कोई सहेज/अपडेट ऑपरेशन नहीं किया गया था - केवल एक प्राप्त/लोड।
तो मेरा सवाल यह है: क्या हाइबरनेट, जब कोई स्पष्ट लेनदेन प्रबंधन परिभाषित नहीं किया जाता है, तो किसी ऑब्जेक्ट का केवल "लोड" होने पर भी एक पंक्ति पर पढ़ने/लिखने के लिए लॉक प्राप्त करने का प्रयास करें। कोई बचत/अद्यतन नहीं किया जाता है।
क्या यह संभव है कि डेटा लोड करने वाली सेवा के चारों ओर एक लेनदेन को परिभाषित करना, और फिर विशेष रूप से लेनदेन पर तुरंत कह रहे हैं एट्रिब्यूट्स हाइबरनेट को पहले से मौजूद मौजूदा लॉक को अनदेखा कर देगा और केवल पढ़ने के उद्देश्यों के लिए डेटा लोड करेगा?
यहाँ कुछ कोड उदाहरण हैं:
हम एक 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>
वास्तविक खरीदऑर्डर लोड करने के लिए कॉल द्वारा लोड किए जा रहे खरीद ऑर्डर इटैम रिकॉर्ड में से एक पर डेडलॉक हो रहा है।
क्या रिकॉर्ड लोड होने पर यह एक डेडलॉक का कारण बन जाएगा यदि किसी अन्य प्रक्रिया द्वारा लॉक किया गया था? और यदि ऐसा है - तो नीचे एक लेनदेन रैपर जोड़ना समस्या को हल करेगा?
<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" कमांड हैं जो सटीक कॉलम पर किए जाते हैं जिन्हें हम डेटाबेस से पढ़ रहे हैं। ऐसा लगता है कि हाइबरनेट स्वचालित रूप से इन रिकॉर्ड्स को डेटाबेस में वापस लिख रहा है (भले ही हम इसे नहीं पूछ रहे हैं)। यह शायद समझाएगा कि डेडलॉक क्यों है।
क्या यह सत्र फ्लश या कुछ ऐसा ही हो सकता है? समाधान की तरह अधिक देखकर लेन-देन रैपर का उपयोग केवल पढ़ने के साथ किया जा सकता है ...
यह बिल्कुल नहीं हो रहा था - लेकिन ऐसा ही लग रहा था। मान कोड में "सेट" नहीं हो रहे थे। हाइबरनेट वास्तव में किसी कारण से उसी डेटा को लिखने की कोशिश कर रहा था (डीबी में डेटा को कभी भी अलग-अलग मानों में अपडेट नहीं किया गया था)। – jonathanq