2010-02-25 25 views
6

मैं जानना चाहता हूं कि दूसरे के अंदर एक लेनदेन खोलना सुरक्षित और प्रोत्साहित है?लेनदेन के भीतर लेनदेन

def foo(): 
    session.begin 
    try: 
      stuffs 
    except Exception, e: 
     session.rollback() 
     raise e 
    session.commit() 

और एक विधि है कि पहले एक कहता है, एक सौदे के अंदर:

मैं एक विधि है

def bar(): 
    stuffs 
    try: 
     foo() #<<<< there it is :) 
     stuffs 
    except Exception, e: 
     session.rollback() 
     raise e 
    session.commit() 
foo पद्धति पर

अगर मैं हो और अपवाद, सभी कार्यों को होगा वापस लुढ़का? और बाकी सब कुछ ठीक काम करेगा? धन्यवाद !!

+1

नेस्टेड लेनदेन (जैसे ओरेकल के ऑटोोनोमस_TRANSACTION) दो मामलों से अलग एक विरोधी पैटर्न के रूप में योग्य हैं: ऑडिटिंग (इसलिए कथन का विवरण वापस लेने के बावजूद भी ऑर्डर किया जाता है) और त्रुटि लॉगिंग (कैप्चर करने के लिए कहां/कब विफल होते हैं)। अन्य सभी मामलों में सेवपॉइंट्स का उपयोग करना चाहिए। हेक, लेन-देन के दायरे को किसी भी कार्य या प्रक्रियाओं में संभाला नहीं जा रहा है; यह प्रतिबद्ध या रोलबैक करने के लिए अंतिम कॉलर की ज़िम्मेदारी होनी चाहिए। –

+0

यह धारणा है। – user

उत्तर

15

एसक्यूएलकेमी में घोंसले के लेनदेन के दो तरीके हैं। एक वर्चुअल लेनदेन है, जहां स्क्लाक्लेमी ट्रैक करता है कि आपने कितनी शुरुआत जारी की है और केवल तभी प्रतिबद्धता है जब बाहरी लेनदेन करता है। हालांकि रोलबैक तुरंत जारी किया जाता है। चूंकि लेन-देन आभासी है - यानी डेटाबेस घोंसले के कुछ भी नहीं जानता है, आप रोलबैक के बाद उस सत्र के साथ कुछ भी नहीं कर सकते हैं जब तक आप सभी बाहरी लेन-देन को रोलबैक नहीं करते। उपयोग वर्चुअल लेनदेन को subtransactions=Truebegin() कॉल पर तर्क जोड़ने की अनुमति देने के लिए। यह सुविधा उन कार्यों के अंदर लेनदेन नियंत्रण का उपयोग करने की अनुमति देने के लिए मौजूद है जो एक दूसरे को कॉल किए बिना ट्रैक रखे बिना ट्रैक कर सकते हैं या नहीं। इसे समझने के लिए, autocommit=True के साथ सत्र कॉन्फ़िगर करें और हमेशा एक लेनदेन समारोह में session.begin(subtransactions=True) जारी करें।

घोंसला लेनदेन का दूसरा तरीका वास्तविक नेस्टेड लेनदेन का उपयोग करना है। वे savepoints का उपयोग कर लागू कर रहे हैं। यदि आप नेस्टेड लेनदेन को रोलबैक करते हैं, तो उस लेनदेन के भीतर किए गए सभी परिवर्तन वापस लुढ़कते हैं, लेकिन बाहरी लेनदेन उपयोग योग्य रहता है और बाहरी लेनदेन द्वारा किए गए किसी भी बदलाव अभी भी वहां हैं। नेस्टेड लेनदेन समस्या session.begin(nested=True) या केवल session.begin_nested() का उपयोग करने के लिए। नेस्टेड लेनदेन सभी डेटाबेस के लिए समर्थित नहीं हैं। SQLAlchemy का टेस्ट स्वीट पुस्तकालय विन्यास समारोह sqlalchemy.test.requires.savepoints समर्थन के बारे में इस का कहना है:

emits_warning_on('mssql', 'Savepoint support in mssql is experimental and may lead to data loss.'), 
    no_support('access', 'not supported by database'), 
    no_support('sqlite', 'not supported by database'), 
    no_support('sybase', 'FIXME: guessing, needs confirmation'), 
    exclude('mysql', '<', (5, 0, 3), 'not supported by database') 

PostgreSQL SQLAlchemy नेस्टेड लेनदेन पर ठीक काम करते हैं।

0

आप नहीं कर सकते, PostgreSQL subtransactions का समर्थन नहीं करता है। आप savepoints का उपयोग करना चाह सकते हैं, लेकिन यह कुछ और है।

+0

ठीक है। लेकिन मैं ऊपर दिए गए कोड को निष्पादित करता हूं और स्क्लेल्चेमी मुझे ऐसा करने की अनुमति देता है। पर्दे के पीछे क्या होता है? – bluefoot

+0

मुझे स्क्लेक्लेमी के साथ कोई अनुभव नहीं है, जो कभी भी आपकी मदद नहीं कर सकता है। लेकिन मुझे पता है कि PostgreSQL subtransactions नहीं कर सकता है, ओरेकल कुछ डेटाबेस में से एक है जो इस चाल को कर सकता है। मैन्युअल देखें http://www.sqlalchemy.org/docs/session.html#managing-transactions कैसे sqlalchemy लेनदेन और savepoints करता है। और परीक्षण, परीक्षण, परीक्षण! अपने ओआरएम पर भरोसा न करें जब ऐसा लगता है कि यह आपको ऐसा करने की अनुमति देता है जो आपका डेटाबेस नहीं कर सकता ... –

+0

अपडेट किया गया लिंक: http://docs.sqlalchemy.org/en/rel_1_0/orm/session_transaction.html#managing -transactions – Kate

0

PostgreSQL घोंसला लेनदेन पर बस ठीक काम करता है।

ठीक है, आपको कोई त्रुटि नहीं मिलेगी (केवल एक चेतावनी), यह सच है। लेकिन आप आंतरिक लेनदेन और बाहरी लेनदेन को रोलबैक नहीं कर सकते हैं, बाहरी लेनदेन भी आंतरिक लेनदेन को रोलबैक करेगा।

BEGIN;

एक्स (foo) मूल्यों ('जॉन') में प्रवेश करें;

BEGIN; - चेतावनी!

वाई (बार) मूल्यों ('जेन') में प्रवेश करें;

COMMIT; - आंतरिक लेनदेन

रोलबैक; - दोनों प्रविष्टियों को रोलबैक करेगा, न केवल पहले, तालिका में "x"

मेरे ज्ञान के लिए, ओरेकल उन विकल्पों में से एक है जिनमें यह विकल्प है।

+3

पोस्टस्ट्रेस्क्ल लेनदेन नेस्टेड नहीं है। SQLAlchemy घोंसला लेनदेन। आंतरिक लेनदेन के परिणामस्वरूप बचत और रिलीज सेवॉइंट/रोलबैक को बचाने के लिए। इसका परिणाम व्यवहार में होता है जो किसी नेस्टेड लेनदेन से अपेक्षा करता है। यह वास्तव में ओरेकल बैकएंड पर SAVEPOINTs के साथ भी लागू किया गया है। मैंने तदनुसार जवाब स्पष्ट किया। –

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