2010-01-29 19 views
5

मैं कोड का एक टुकड़ा है कि एक पृष्ठभूमि प्रक्रिया है जिसकेDjango और Postgres लेनदेन रोलबैक

तरह
from django.db import transaction 

try: 

    <some code> 

    transaction.commit() 

except Exception, e: 

    print e 

    transaction.rollback() 

लग रहा है एक परीक्षण में काम करता है, मैं डेटा है कि एक डेटाबेस त्रुटि का कारण बनता है के साथ <some_code> टूट गया। अपवाद

File "/home/commando/Development/Diploma/streaminatr/stream/testcases/feeds.py", line 261, in testInterrupt 

    form.save(self.user1)                      

File "/usr/lib/pymodules/python2.5/django/db/transaction.py", line 223, in _autocommit      

    return func(*args, **kw)                     

File "/home/commando/Development/Diploma/streaminatr/stream/forms.py", line 99, in save      

    print(models.FeedChannel.objects.all())                 

File "/usr/lib/pymodules/python2.5/django/db/models/query.py", line 68, in `__repr__ `      

    data = list(self[:REPR_OUTPUT_SIZE + 1])                 

File "/usr/lib/pymodules/python2.5/django/db/models/query.py", line 83, in `__len__ `       

    self._result_cache.extend(list(self._iter))                

File "/usr/lib/pymodules/python2.5/django/db/models/query.py", line 238, in iterator      

    for row in self.query.results_iter():                  

File "/usr/lib/pymodules/python2.5/django/db/models/sql/query.py", line 287, in results_iter    

    for rows in self.execute_sql(MULTI):                  

File "/usr/lib/pymodules/python2.5/django/db/models/sql/query.py", line 2369, in execute_sql    

    cursor.execute(sql, params)                    

InternalError: current transaction is aborted, commands ignored until end of transaction block 

यह मेरी अपेक्षा है। बुरी बात यह है कि जब भी मैं transaction.rollback कहलाता हूं तो डीबी तक पहुंचने का प्रयास करते समय भी मुझे वही त्रुटि मिलती है। लेनदेन को सफलतापूर्वक रोलबैक करने के लिए मुझे क्या करना चाहिए और कनेक्शन को एक बार फिर प्रयोग करने योग्य बनाना चाहिए?

बीटीडब्ल्यू, मैंने कोड को डीबग करने के लिए print connection.queries डालने का भी प्रयास किया, और यह हमेशा एक खाली सूची देता है। क्या यह हो सकता है कि Django कुछ अन्य डीबी कनेक्शन का उपयोग कर रहा है?

कोड अनुरोध-प्रतिक्रिया चक्र के बाहर चलाया जाता है। मैंने ट्रांज़ेक्शन मिडलवेयर को चालू और बंद करने की कोशिश की, लेकिन इसका कोई प्रभाव नहीं पड़ा।

मैं Django 1.1 और पोस्टग्रेस 8.4 का उपयोग कर रहा हूं।

+0

यदि आप "try" कथन के "अन्य" खंड में "license.commit()" को स्थानांतरित करते हैं तो क्या होता है? –

+0

बस वही व्यवहार। –

+0

क्या आपके पास डीबी सर्वर पर नियंत्रण है? यदि आप क्वेरी लॉगिंग चालू करते हैं - "log_statement = all" (ALTER DATABASE SET log_statement to 'all')। फिर इसे पुनः प्रयास करें और लॉग पर एक नज़र डालें। –

उत्तर

6

डिफ़ॉल्ट testcase लेनदेन के बारे में कुछ भी पता नहीं है, तो आप इस मामले में TransactionalTestCase उपयोग करने के लिए की जरूरत है।

+0

धन्यवाद, मुझे इस दस्तावेज़ीकरण को याद आया! –

2

मैंने इस सजावट को लेनदेन मिडलवेयर source के आधार पर लिखा था। उम्मीद है कि यह मदद करता है, मेरे लिए पूरी तरह से काम करता है।

def djangoDBManaged(func): 
    def f(*args, **kwargs): 
     django.db.transaction.enter_transaction_management() 
     django.db.transaction.managed(True) 
     try: 
      rs = func(*args, **kwargs) 
     except Exception: 
      if django.db.transaction.is_dirty(): 
       django.db.transaction.rollback() 
      django.db.transaction.leave_transaction_management() 
      raise 
     finally: 
      if django.db.transaction.is_managed(): 
       if django.db.transaction.is_dirty(): 
        django.db.transaction.commit() 
       django.db.transaction.leave_transaction_management() 
     return rs 
    # So logging gets the right call info whatever the decorator order is 
    f.__name__ = func.__name__ 
    f.__doc__ = func.__doc__ 
    f.__dict__ = func.__dict__ 
    return f 
संबंधित मुद्दे