2009-03-19 14 views
5

हम ओरेकल डेडलॉक (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" कमांड हैं जो सटीक कॉलम पर किए जाते हैं जिन्हें हम डेटाबेस से पढ़ रहे हैं। ऐसा लगता है कि हाइबरनेट स्वचालित रूप से इन रिकॉर्ड्स को डेटाबेस में वापस लिख रहा है (भले ही हम इसे नहीं पूछ रहे हैं)। यह शायद समझाएगा कि डेडलॉक क्यों है।

क्या यह सत्र फ्लश या कुछ ऐसा ही हो सकता है? समाधान की तरह अधिक देखकर लेन-देन रैपर का उपयोग केवल पढ़ने के साथ किया जा सकता है ...

उत्तर

1

हमने अंततः यह निर्धारित किया कि समाधान इसे केवल पढ़ने के लिए लेनदेन में लपेटना था।

मुझे स्पष्ट नहीं है कि क्यों हम सेटर्स का उपयोग नहीं कर रहे थे (बस डेटा पढ़ रहे थे) - डेटाबेस में कुछ भी नहीं बदला जा रहा था। लेकिन किसी कारण से हाइबरनेट उसी डेटा को दोबारा लिखने की कोशिश कर रहा था और एक लॉक का कारण बन रहा था जब एक और प्रक्रिया ने उन रिकॉर्ड्स को पढ़ने की कोशिश की।

पढ़ने का उपयोग केवल लेनदेन से समस्या दूर हो गई!

<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> 

0

क्या आपने डेटाबेस में किसी भी ट्रिगर्स की जांच की है? क्या आप सुनिश्चित हैं कि यह हाइबरनेट है और कुछ अन्य पंक्तियों को अपडेट करने वाली कोई अन्य प्रक्रिया नहीं है? हो सकता है कि आखिरी पठन का टाइमस्टैम्प संग्रहीत करने वाला एक कॉलम हो और जब भी पंक्ति पढ़ी जाए तो इसे अपडेट किया जाता है (हालांकि मुझे अपने सिर के शीर्ष से याद नहीं किया जा सकता है कि आप चयन ट्रिगर कर सकते हैं) ...

2

अनैच्छिक जब आप सेटर्स का उपयोग करते हैं तो वे हाइबरनेट के साथ अपडेट हो सकते हैं जो वास्तव में सेट किए गए मान में हेरफेर करते हैं। एक उदाहरण एक स्ट्रिंग विशेषता के लिए एक सेटटर होगा जो शून्य के मान को "" के साथ बदल देता है। एक संभावित उम्मीदवार भी संग्रह हैं। सुनिश्चित करें कि सेटर्स निहित संग्रह को प्रतिस्थापित नहीं करते हैं। यदि आप एक ही सामग्री वाले किसी अन्य संग्रह के साथ किसी इकाई के संग्रह को प्रतिस्थापित करते हैं, तो हाइबरनेट इसे पूरा करने में सक्षम नहीं होगा और पूर्ण संग्रह को अपडेट नहीं करेगा।

+0

यह बिल्कुल नहीं हो रहा था - लेकिन ऐसा ही लग रहा था। मान कोड में "सेट" नहीं हो रहे थे। हाइबरनेट वास्तव में किसी कारण से उसी डेटा को लिखने की कोशिश कर रहा था (डीबी में डेटा को कभी भी अलग-अलग मानों में अपडेट नहीं किया गया था)। – jonathanq

0

जेन्स

ऑन तुम करीब से अपने setters और getters का निरीक्षण किया और अगर वे जैसे नई तिथि अलग-अलग कॉल पर एक अलग मान (देखने के लिए) की जरूरत को जोड़ने के लिए सही है - यह एक नया value- प्रत्येक वापसी होगी समय कहा जाता है और हाइबरनेट को लगता है कि ऑब्जेक्ट बदल गया है

0

एक बात करने के लिए दिलचस्प अपने log4j विन्यास में

log4j.logger.org.hibernate.persister.entity.AbstractEntityPersister = ट्रेस जोड़ने के लिए

है। ऐसा हाइबरनेट करने से लॉग इन होगा कि किसी इकाई को डेटाबेस में अद्यतन की आवश्यकता क्यों है। हमारे पास कुछ समस्याएं थीं जब "डीबी में अपडेट होने के कारण संपत्ति कम हो गई थी। ऐसा करके हम ऐसी समस्याओं को दूर करने में सक्षम थे।

0

मैंने यह समस्या हमारे सिस्टम में तब देखी है जब हमारे पास इंडेक्स गायब थे। डेटाबेस में निष्पादित किए जा रहे प्रश्न मुख्य कॉलम पर अनुपलब्ध इंडेक्स के कारण तालिका को लॉक कर रहे हैं।