2009-08-02 11 views
18

Im psycopg2 के साथ झुकाव, और जबकि .comit() और .rollback() कोई है .begin() या लेनदेन शुरू करने के समान है, या ऐसा लगता है? मैं कैसे लेनदेन psycopg2 के साथ काम करते हैंमैं psycopg2/पायथन डीबी एपीआई के साथ डेटाबेस लेनदेन कैसे कर सकता हूं?

db.begin() # possible even set the isolation level here 
curs = db.cursor() 
cursor.execute('select etc... for update') 
... 
cursor.execute('update ... etc.') 
db.commit(); 

करने के लिए तो सक्षम होने के लिए उम्मीद थी,? मैं अलगाव स्तर को कैसे सेट/बदलूं?

उत्तर

23

db.set_isolation_level(n) का उपयोग करें, मान लें कि db आपकी कनेक्शन ऑब्जेक्ट है। फेडरिको रूप here लिखा था, n का अर्थ है:

0 -> autocommit 
1 -> read committed 
2 -> serialized (but not officially supported by pg) 
3 -> serialized 

रूप here प्रलेखित, psycopg2.extensions आप इस प्रयोजन के लिए प्रतीकात्मक स्थिरांक देता है:

Setting transaction isolation levels 
==================================== 

psycopg2 connection objects hold informations about the PostgreSQL `transaction 
isolation level`_. The current transaction level can be read from the 
`.isolation_level` attribute. The default isolation level is ``READ 
COMMITTED``. A different isolation level con be set through the 
`.set_isolation_level()` method. The level can be set to one of the following 
constants, defined in `psycopg2.extensions`: 

`ISOLATION_LEVEL_AUTOCOMMIT` 
    No transaction is started when command are issued and no 
    `.commit()`/`.rollback()` is required. Some PostgreSQL command such as 
    ``CREATE DATABASE`` can't run into a transaction: to run such command use 
    `.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)`. 

`ISOLATION_LEVEL_READ_COMMITTED` 
    This is the default value. A new transaction is started at the first 
    `.execute()` command on a cursor and at each new `.execute()` after a 
    `.commit()` or a `.rollback()`. The transaction runs in the PostgreSQL 
    ``READ COMMITTED`` isolation level. 

`ISOLATION_LEVEL_SERIALIZABLE` 
    Transactions are run at a ``SERIALIZABLE`` isolation level. 


.. _transaction isolation level: 
    http://www.postgresql.org/docs/8.1/static/transaction-iso.html 
+0

अच्छा। क्या यह autocommit करने के लिए डिफ़ॉल्ट है? एन = 1,2 या 3 सेट करते समय लेनदेन शुरू होता है? अंतिम प्रतिबद्ध/रोलबैक के बाद से नया कर्सर बनाना, या डीबी पर बस हर ऑपरेशन बनाना? – Leeeroy

+0

ऑटोकॉमिट अधिकांश डीबीएमएस में डिफ़ॉल्ट है। –

+1

एलेक्स ने पूछे जाने के बाद और सामान जोड़ा। और यह कहता है कि READ_COMMITED psycopg2 – Leeeroy

5

मैं स्पष्ट रूप से देखने के लिए मेरी लेनदेन कर रहे हैं जहां पसंद करते हैं:

  • कर्सर.एक्सक्यूट ("BEGIN")
  • कर्सर .execute ("COMMIT")
+2

क्या यह ऑटोोकॉमिट के साथ या बंद है? क्या यह साइकोप 2, या अन्य डेटाबेस मॉड्यूल को भ्रमित करेगा? ओडीबीसी का लेनदेन प्रबंधन पायथन डीबी एपीआई के समान दृष्टिकोण का उपयोग करता है, और मैंने ओडीबीसी इंटरफ़ेस को विभाजित करने वाले SQL लेनदेन प्रबंधन आदेशों का उपयोग करने के लिए स्पष्ट चेतावनियां * नहीं * देखी हैं (उदाहरण के लिए http://msdn.microsoft.com/en-us/ पुस्तकालय/ms131281.aspx)। –

+1

कृपया ऐसा मत करें। आप autocommit कार्यक्षमता के खिलाफ लड़ेंगे, इस बात की कोई गारंटी नहीं है कि परिणाम सुंदर होगा। –

+2

यह ऑटोकॉमिट ऑफ के साथ है। – peufeu

12

BEGIN पायथन मानक डीबी एपीआई हमेशा निहित है। जब आप डेटाबेस के साथ काम करना शुरू करते हैं तो ड्राइवर BEGIN जारी करता है और COMMIT या ROLLBACK के बाद BEGIN जारी किया जाता है। विनिर्देश के साथ अनुपालन एक पायथन डीबी एपीआई हमेशा इस तरह से काम करना चाहिए (न केवल postgresql)।

आप एलेक्स मार्टेलि द्वारा इंगित db.set_isolation_level(n) के साथ इस सेटिंग को अलोकॉमीट में बदल सकते हैं।

जैसा कि Tebas ने कहा कि शुरुआत अंतर्निहित है लेकिन SQL को निष्पादित होने तक निष्पादित नहीं किया जाता है, इसलिए यदि आप किसी SQL को निष्पादित नहीं करते हैं, तो सत्र लेनदेन में नहीं है।

+2

क्या यह सच है? मेरा मानना ​​है कि प्रतिबद्ध() या रोलबैक() के कॉल के बाद _not_ तुरंत एक और BEGIN भेजता है - यह अगले निष्पादन() के साथ निहित भेजता है। प्रतिबद्धता()/रोलबैक() के बाद कनेक्शन 'लेनदेन में निष्क्रिय' के बजाय राज्य 'निष्क्रिय' में है। – Tebas

+0

एक प्रतिबद्धता के बाद()/रोलबैक() कनेक्शन राज्य 'निष्क्रिय' में है। पायथन डीबी एपीआई केवल एक और निष्पादन के बाद एक और BEGIN भेज देगा() यदि आपका प्रोग्राम कभी समाप्त नहीं होता है तो आप डेडलॉक नहीं बनाते हैं। एक बार जब आप execute() को कॉल करते हैं तो सारांशित करने के लिए आपको() या रोलबैक() करना चाहिए यदि नहीं, तो प्रोग्राम "लेनदेन में निष्क्रिय" होगा। – praveenak

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