2013-02-22 16 views
15

में लेनदेन का उपयोग करते समय एक पोस्ट प्रतिबद्ध बनाना, कुछ कारणों से मैंने मैन्युअल रूप से लेनदेन प्रतिबद्धता का संचालन किया है और स्प्रिंग प्लेटफार्म ट्रान्सएक्शन मैनेजर का उपयोग करके वापस रोल किया है, मुझे जो करना है वह एक हुक सेट अप करना है ताकि लेनदेन के बाद एक पोस्ट प्रतिबद्ध कार्रवाई हो प्रतिबद्ध।वसंत

को देख कर:

void commit(TransactionStatus status) throws TransactionException; 

मैं नहीं कर सकते देखने के मैं कैसे निर्धारित कर सकते हैं एक सौदे यह assumming इसलिए यदि कोई expception फेंक दिया जाता है की तुलना में सफल अन्य था।

और मैं एओपी का उपयोग एक विकल्प के रूप में कर सकता था, लेकिन प्रोग्रामिंग के बारे में क्या करना है, शायद कॉलबैक विधि का उपयोग कर?

उत्तर

33

आप वास्तव में आप क्या चाहते हैं एक सरल तरीका मिल सकता है, TransactionSynchronizationManager और TransactionSynchronization साथ

के साथ, आप स्थिर तरीकों वर्तमान लेन-देन के बारे में जानकारी प्राप्त करने के लिए है, और आप रजिस्टर कर सकते हैं एक TransactionSynchronization जो आप स्वचालित रूप से करने की अनुमति देता के बाद प्रतिबद्ध के रूप में आप फोन है कि

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){ 
      void afterCommit(){ 
       //do what you want to do after commit 
      } 
}) 

पता है कि TransactionSynchronization एक प्रति- पर है रहो थ्रेड आधार (जो अक्सर मूल वेब अनुरोध के लिए कोई समस्या नहीं है)।

+0

ठीक है यह बहुत अच्छा लगता है ... तो अगर यह एकल धागे से बंधे हैं, और कॉल रिकर्सिव है ...एक सिंगल थ्रेड शुरू होता है एक लेनदेन एक सिंक्रनाइज़ेशन (1 - प्रतिबद्धता के बाद) पंजीकृत करता है और उसके बाद उस लेनदेन में शामिल होने वाली दूसरी विधि को सिंक्रनाइज़ेशन (2 - प्रतिबद्धता) पंजीकृत करता है .... जब यह काम करता है .. मुझे लगता है कि सिंक्रनाइज़र के बाद केवल एक ही लगता है उन्हें निकाल दिया जाएगा ... उन्हें एक सेट में संग्रहीत किया जा रहा है? .. शायद गलत है मुझे परीक्षण करना होगा ... – user1555190

+0

'लेनदेन सिंक्रनाइज़ेशन 'ऑब्जेक्ट्स थ्रेड द्वारा एक सूची के रूप में रखा जाता है, सूची जिसे आप' लेनदेन सिंक्रनाइज़ेशन प्रबंधक 'के साथ पुनर्प्राप्त कर सकते हैं। getSynchronizations() ' – Grooveek

+0

मेरा मानना ​​है कि इसे एक सेट के रूप में रखा गया है, और उसके बाद एक सूची के रूप में लौटाया गया है ... सेट <लेनदेन सिंक्रनाइज़ेशन> synchs .............. नया ArrayList (synchs) लौटाएं ..... मैं सिर्फ दो सोचने के बाद सोच रहा हूं ... – user1555190

1

कुछ कारणों से मेरी परियोजनाओं में से एक में मुझे PlatformTransactionManager का उपयोग करना पड़ा। इसलिए मैंने org.springframework.transaction.support.TransactionTemplate का उपयोग करने के लिए मजबूर किया।

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/transaction/support/TransactionTemplate.html

मुख्य लाभ यह है कि यदि आप PlatformTransactionManager सही ढंग से लागू है, तो आप के लिए प्रतिबद्ध/रोलबैक पुस्तिका से परेशान करने की जरूरत नहीं है। ट्रांज़ेक्शन टेम्पलेट का कम से कम स्रोत कोड आपको मदद कर सकता है यदि आपको अधिक विशिष्ट चीज़ की आवश्यकता है।

यह बहुत बस का उपयोग करने के तरीके:

config.xml

<bean name="transactionTemplate" 
      class="org.springframework.transaction.support.TransactionTemplate"> 
    <property name="transactionManager" ref="platformTransactionManager"/> 
</bean> 

MyServiceImpl.java

 

@Service 
public class MyServiceImpl implements MyService { 

    @Autowired 
    private TransactionTemplate transactionTemplate; 

    public Entity getSomethingWithTx(final long id) { 

     return transactionTemplate.execute(new TransactionCallback<Entity>() { 
      @Override 
      public Entity doInTransaction(TransactionStatus status) { 
       //TODO implement 
      } 
     }); 
    } 

+0

यही वास्तव में चीजों के मैनुअल कोडन पक्ष के साथ मदद करता है, लेकिन यह कैसे एक सौदे मौसम बताने के लिए संभव है वापस ले जाया गया है या सफलतापूर्वक प्रतिबद्ध किया गया है, मैं स्थिति देख सकता हूं। अपूर्ण() .. लेकिन इसका मतलब एक सफल रोल वापस या सफल प्रतिबद्धता हो सकता है ...? – user1555190

+1

ट्रांजैक्शन केवल दो मामलों में रोलबैक होगा: कॉलबैक कोड एक अपवाद फेंकता है जो इंट्रेन्सक्शन करता है या एक अंतर्निहित रोलबैक कॉल होता है (जो दृढ़ता से निराश होता है और संभवतः एक अप्रत्याशित रोलबैक अपवाद उत्पन्न करेगा)। इसलिए आप सुरक्षित रूप से यह मान सकते हैं कि अगर कुछ प्राप्त हो रहा है तो विथ टीएक्स ने एक फेंक नहीं दिया, लेनदेन सफलतापूर्वक किया गया। – mrembisz

6

ग्रूवेक के जवाब को श्रेय और इसके तहत एलेक्स की टिप्पणी - मैंने इसे यहां रखा क्योंकि संयुक्त सुझाव एक ठोस और क्लीनर समाधान प्रदान करते हैं जो नेट के चारों ओर खोजना मुश्किल है।

वसंत 4+ का उपयोग करना। यदि आप एक @Transactional पद्धति पर एक कॉलबैक की जरूरत है इसे सफलतापूर्वक बस जोड़ने के लिए प्रतिबद्ध के बाद कि विधि की शुरुआत में:

@Service 
public class OneService { 

    @Autowired 
    OneDao dao; 

    @Transactional 
    public void a transactionalMethod() { 
     TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){ 
      public void afterCommit(){ 
       //do stuff right after commit 
       System.out.println("commit!!!"); 

      } 
     }); 
     //do db stuff 
     dao.save(); 
    } 
} 
+1

पर आधारित मेरे उत्तर की जांच करें @ मिचेल को उनके उत्तर के लिए धन्यवाद। लेन-देन रोल-बैक के लिए यह दृष्टिकोण "अनुवर्ती समाप्ति (int स्थिति)" और स्थिति की जांच == लेनदेन सिंक्रनाइज़ेशन का उपयोग करके काम करता है। STATUS_ROLLED_BACK – deep