2010-10-07 11 views
5

विफल रहता है, तो मैं एक साधारण एप्लिकेशन (स्प्रिंग + हाइबरनेट + पोस्टग्रेएसक्ल डीबी) लिख रहा हूं। मैं सिर्फ नमूना वस्तु बनाने और डीबी में बने रहने की कोशिश कर रहा हूं।स्प्रिंग लेनदेन - पिछले डीबी अपडेट के स्वचालित रोलबैक जब एक डीबी अपडेट

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactoryVsm" /> 
</bean> 

<bean id="testService" class="com.test.service.TestServiceImpl"> 
    <property name="testDao" ref="testDao"/> 
</bean> 

<bean id="testDao" class="com.test.dao.TestDaoImpl> 
    <property name="sessionFactory" ref="sessionFactoryVsm"/> 
</bean> 

: संदर्भ -

मैं एक साधारण जावा वर्ग मुख्य विधि मैं कहाँ applicationContext भरी हुई है और नीचे

TestService srv = (TestService)factory.getBean("testService"); 

आवेदन संदर्भ के रूप में सेवा वर्ग के संदर्भ में मिल गया है चलाने टेस्ट सर्विस में मैंने टेस्टडाओ इंजेक्शन दिया है। परीक्षण सेवा विधि में मैंने कर्मचारी वस्तुओं emp1 और emp2 और दो बार कॉल करने के लिए दाओ को कॉल करने के लिए बनाया है।

TestDaoImpl कोड:

public void saveOrUpdate(BaseDomainModel baseObject) { 

    Session session = null; 
    try { 
     session = getHibernateTemplate().getSessionFactory().openSession(); 
     session.saveOrUpdate(baseObject); 
     session.flush(); 
    } catch (Exception e) { 
     logger.error("Generic DAO:saveOrUpdate::" + e); 
     e.printStackTrace(); 
    } finally { 
     if (session != null) { 
      session.close(); 
     } 
    } 

} 

emp1 भी असफल चाहिए जब emp2 अद्यतन विफल रहता है। मैं उसको कैसे करू। अग्रिम

अपडेट किया गया में सलाह कृपया

धन्यवाद:

धन्यवाद नंदा। मैंने घोषणात्मक लेनदेन की कोशिश की। लेकिन यह काम नहीं कर रहा है। emp1 जारी रहता है और पीछे नहीं घुमाया जाता है दूसरा द्वितीय कॉल विफल रहता है। मैंने विधि में लेनदेन सलाह जोड़ दी है।

अगर लेन-देन सलाह या लागू नहीं होती है मैं प्रचार करने के लिए "NOT_SUPPORTED" में बदल परीक्षण करने के लिए। लेकिन अभी भी emp1 जारी रहता है। उम्मीद है कि हमें ट्रांजैक्शन नहीं मिला होना चाहिए अपवाद का प्रकार। कृपया सलाह दें ।

UPDATED

@seanizer - अद्यतन के लिए धन्यवाद। मैंने
@ ट्रांज़ेक्शनल (प्रचार = प्रचार .NOT_SUPPORTED) सार्वजनिक शून्य saveEmp (कर्मचारी emp) उस सेवा विधि में जोड़ने का भी प्रयास किया है। लेकिन यह काम नहीं किया। इसके अलावा संग्रह को पुन: व्यवस्थित करना केवल तभी अच्छा होता है जब मुझे एक दाओ को फोन करने की आवश्यकता हो। यदि मुझे obj1 और obj2 को बनाए रखने के लिए दो अलग-अलग दाओ को कॉल करना है- इससे मदद नहीं मिल सकती है। यह जांचने के लिए कि लेनदेन लागू हो रहा है या नहीं, मुझे @ ट्रान्सएक्शनल (प्रचार = प्रचार .NOT_SUPPORTED) प्राप्त होता है। लेकिन अभी भी obj1 जारी रहा है। मुझे संदेह है कि अगर XML कॉन्फ़िगरेशन/एनोटेशन दिया गया है तो सही है।

<bean id="txManager" 
     class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactoryVsm" /> 
    </bean> 

<tx:advice id="txAdvice" transaction-manager="txManager"> 
    <tx:attributes> 
     <tx:method name="saveEmp" propagation="REQUIRED" rollback-for="Exception"/> 
     <tx:method name="*"/> 
    </tx:attributes> 
</tx:advice> 
<aop:config> 
    <aop:pointcut id="testServiceOperation" expression="execution(*com.test.service.*(..))"/> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="testServiceOperation"/> 
    </aop:config> 

मैं transactionManager के लिए org.springframework.orm.hibernate3.HibernateTransactionManager उपयोग कर रहा हूँ देखें। क्या ये सही है ?


मैं अपने अपवाद वर्ग बनाया है myRuntimeExp RuntimeException से विस्तार और सेवा विधि के लिए दाव विधि से एक ही फेंक अपडेट किया गया। लेकिन अभी भी रोलबैक नहीं हो रहा है।मुझे संदेह है कि अगर मैंने applnContext.xml में कॉन्फ़िगरेशन सही तरीके से दिए हैं। क्या कोई मेरी मदद कर सकता है कि यह जांचने के लिए कि क्या लेनदेन सलाह/एनोटेशन विधि पर लागू किया जा रहा है या नहीं?

मैं

session = getHibernateTemplate().getSessionFactory().openSession(); 

उपयोग कर रहा था लेकिन यह वर्तमान सत्र होना चाहिए और यह ठीक काम कर रहा है: वहाँ एक डिबगिंग मोड में चल रहा है और जाँच

जारी करने की किसी भी तरह से है।

session = getHibernateTemplate().getSessionFactory().getCurrentSession(); 

उत्तर

4

आप कथात्मक लेनदेन प्रबंधन का उपयोग करते हैं, तो आप इस बॉयलरप्लेट के सबसे खो सकते हैं:

TestDaoImpl:

private SessionFactory sessionFactory; 

public void setSessionFactory(SessionFactory f){ 
    this.sessionFactory = f; 
} 

public void saveOrUpdate(BaseDomainModel baseObject) { 
    Session session = sessionFactory.getCurrentSession(); 
    session.saveOrUpdate(baseObject); 
} 

और आप लेन-देन सेवा परत @Transactional का उपयोग करने से निपटने नियंत्रित कर सकते हैं (या एक्सएमएल विन्यास)

टेस्ट सेवा सेवा:

private TestDao testDao; 

public void setTestDao(TestDao d){ 
    this.testDao = d; 
} 

@Transactional // one transaction for multiple operations 
public void someServiceMethod(Collection<BaseDomainModel> data){ 
    for(BaseDomainModel baseObject : data) 
     testDao.saveOrUpdate(baseObject); 
} 

संदर्भ:

1

आप TestServiceImpl में sessionFactory डाल सकते हैं और वहां सत्र खोल सकते हैं।

+0

क्या वसंत घोषणात्मक लेनदेन इस मामले में सहायता करता है? – Vaandu

+0

हां बेशक, घोषित करें कि दाओ और सेवा स्तर पर लेनदेन की आवश्यकता है। यदि दाओ का पता चलता है कि सेवा ने लेनदेन खोला है, तो यह नए लेनदेन – nanda

+0

बनाने के बजाय इसका उपयोग करेगा, मैं असहमत हूं, सेवा विधियों पर लेनदेन की आवश्यकता होनी चाहिए, न कि दाओ विधियों। इस तरह एक सेवा कॉल परमाणु हो सकता है भले ही यह कई दाओ विधियों का उपयोग करता है (हाँ, मुझे पता है कि आप मौजूदा लेनदेन में शामिल होने से भी इसे प्राप्त कर सकते हैं, लेकिन मैं परतों का एक साफ अलगाव पसंद करता हूं) –

4

डिफ़ॉल्ट रूप से, स्प्रिंग केवल अनियंत्रित अपवाद के लिए वापस रोल। आपको रोलबैक प्रदान करना होगा-attribute के लिए और निर्दिष्ट करें कि आप किस अपवाद को पकड़ने की कोशिश कर रहे हैं।


स्प्रिंग documentation से:

हालांकि, कृपया ध्यान दें कि स्प्रिंग फ्रेमवर्क के लेन-देन बुनियादी ढांचे कोड डिफ़ॉल्ट रूप से, केवल एक सौदे रोलबैक के लिए क्रम के मामले में प्रतीक होगा, अनचेक अपवाद; यानी, फेंक दिया अपवाद रनटाइम अपवाद का उदाहरण या उप-वर्ग है। (त्रुटियाँ भी होगा - डिफ़ॉल्ट रूप से -। एक रोलबैक में परिणाम) अपवाद है कि एक लेन-देन संबंधी विधि से फेंक दिया जाता है लेनदेन में नहीं परिणाम वापस शुरू की जा रही होगी जांच की गई।

+0

नोट करें कि आपको यह भी जोड़ने की आवश्यकता है: virgium03

+0

@ virgium03 - धन्यवाद। आप उपर्युक्त एक्सएमएल स्निपर देख सकते हैं जहां मैंने दिया है। यह ध्यान रखना चाहिए - क्या मैं सही हूँ? – Vaandu

+0

भी, आप लॉगिंग स्तर को डीबग करने के लिए चालू कर सकते हैं और देख सकते हैं कि लेन-देन कब किया जाता है, वापस रोल किया जाता है – virgium03

2

यहाँ, ये स्निपेट हो और आशा है कि वे आपकी मदद करेंगे:

<bean id="abstractService" 
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" 
abstract="true"> 
<property name="transactionManager" ref="transactionManager" /> 
<property name="transactionAttributes"> 
    <props> 
     <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> 
     <prop key="add*">PROPAGATION_REQUIRED, -Exception</prop> 
     <prop key="update*">PROPAGATION_REQUIRED, -Exception</prop> 
     <prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop> 
     <prop key="delete*">PROPAGATION_REQUIRED, -Exception</prop> 
     <prop key="save*">PROPAGATION_REQUIRED, -Exception</prop> 
    </props> 
</property> 
</bean> 

<bean id="persistenceServiceTarget" class="com.blahblah.server.service.impl.PersistenceServiceImpl"> 
<property name="persistenceDAO" ref="persistenceDAO" /> 
</bean> 
<bean id="persistenceService" parent="abstractService"> 
    <property name="target" ref="persistenceServiceTarget" /> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="abstractDAO" 
class="org.springframework.orm.hibernate3.support.HibernateDaoSupport" 
abstract="true"> 
<property name="sessionFactory"> 
    <ref bean="webSessionFactory" /> 
</property> 
</bean> 

<bean id="persistenceDAO" class="com.blahblah.server.dao.impl.PersistenceDAOImpl" 
parent="abstractDAO"> 
</bean> 

ये बातें है कि आप की जरूरत होनी चाहिए। उन्हें एक ही फाइल में होना जरूरी नहीं है, शायद उन्हें सेवाओं और दासों के बीच विभाजित करें।

1

एक और बिंदु यह जांचना है कि क्या डेटाबेस लेनदेन का समर्थन करता है

संबंधित मुद्दे