2013-11-25 8 views
8

का उपयोग करके नेस्टेड लेनदेन को बचाने के लिए रोलबैक कैसे करें मेरे पास डेटाबेस से कनेक्ट करने के लिए हाइबरनेट का उपयोग कर जावाईई एप्लिकेशन है। मेरे आवेदन के कुछ हिस्सों में मैंने उस विधि को कॉल किया है जिसमें @Transactional एनोटेशन है। इनमें से कुछ मामलों में, मैं पूरे लेनदेन (बाहरी सेवा-विधि कॉल, और आंतरिक) को रोलबैक करना चाहता हूं। और कुछ मौकों पर मैं आंतरिक सेवा की शुरुआत में केवल आंतरिक सेवा-विधि कॉल (यानी savepoint पर रोलबैक रोलबैक करना चाहता हूं)।हाइबरनेट

पहला भाग पहले से ही मौजूद है, लेकिन मुझे दूसरी समस्या है। जब मैं निम्नलिखित करता हूं, तो मुझे संदेश के साथ "अप्रत्याशित रोलबैक अपवाद" मिलता है "लेनदेन वापस लुढ़का क्योंकि इसे केवल रोलबैक के रूप में चिह्नित किया गया है"।

@Service 
public class OuterService{ 

    @AutoWired 
    private InnerServcie innerService; 

    @Transactional 
    public void outer(){ 
     try{ 
      innerService.inner(); 
     }catch(RuntimeException e){ 
      //if i dont throw this up, it will give me the "UnexpectedRollbackException" 
      System.out.println("I cought a RuntimeException"); 
     } 
    } 
} 

@Service 
public class InnerServcie{ 
    @Transactional 
    public void inner(){ 
     //here we insert some data into db using hibernate 
     //but something goes wrong and an exception is thrown 
    } 
} 

उत्तर

0

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

बाद आप क्या चाहते है, तो बस

@Transactional(propagation = Propagation.REQUIRES_NEW) 
+0

मैं भीतरी विधि को यह जोड़ा, और मैं एक गतिरोध प्राप्त करें! कोई विचार? – hfm

0

साथ अपने भीतर विधि व्याख्या अपने TransactionManagerfalse के globalRollbackOnParticipationFailure विशेषता सेट करके देखें।

अधिक जानकारी के लिए http://docs.spring.io/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/transaction/support/AbstractPlatformTransactionManager.html#setGlobalRollbackOnParticipationFailure(boolean) देखें।

6

जो सुविधा आप खोज रहे हैं उसे सेवपॉइंट्स कहा जाता है। वे कड़ाई से कह रहे हैं, घोंसले लेनदेन, लेकिन परिणामस्वरूप एसक्यूएल निर्देश श्रृंखला में मील का पत्थर, जिसके लिए आप रोलबैक कर सकते हैं। सेवपॉइंट पर वापस रोलिंग का मतलब है कि सेवपॉइंट बनाने के पल से जारी सभी निर्देशों को अमान्य कर देना, ताकि आपके पास एकाधिक सेवपॉइंट्स हो सकें, लेकिन आप केवल और और सेवपॉइंट के बीच रोलबैक निर्देशों को केवल 2 सेवपॉइंट्स के बीच नहीं कर सकते हैं!

स्प्रिंग मैन्युअल रूप से JdbcTransactionObjectSupport का उपयोग करते समय, और @Transactional एनोटेशन का उपयोग करते समय सेवपॉइंट का समर्थन करता है।

दस्तावेज़ http://docs.spring.io/spring/docs/2.5.3/reference/transaction.html बिंदु 9.5.7.3 आप Propagation.NESTED का उपयोग करना चाहिए के अनुसार।

हालांकि, यह विकल्प आपके मामले में उपलब्ध नहीं हो सकते हैं। जावाडोक से:

नोट: नेस्टेड लेनदेन का वास्तविक निर्माण केवल विशिष्ट लेनदेन प्रबंधकों पर काम करेगा। बॉक्स में से, यह केवल जेडीबीसी 3.0 ड्राइवर पर काम करते समय जेडीबीसी डेटासोर्स ट्रान्सएक्शन मैनेजर पर लागू होता है। कुछ जेटीए प्रदाता भी नेस्टेड लेनदेन का समर्थन कर सकते हैं।

अंतिम उपाय के रूप में, आप सीक्यूएल निर्देशों को सीधे सहेजने के लिए प्रारंभ/रोलबैकिंग जारी कर सकते हैं।

PostgreSQL के लिए यह होगा:

SAVEPOINT foo; 

ROLLBACK TO SAVEPOINT foo; 

स्रोत: http://www.postgresql.org/docs/8.2/static/sql-rollback-to.html