DatabaseError: वर्तमान लेन-देन निरस्त कर दिया जाता है, लेन-देन ब्लॉक के अंत तक आदेशों को अनदेखा कर दिया जाता है?


252

मुझे संदेश के साथ बहुत सारी त्रुटियां मिलीं:

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

Django परियोजना के डेटाबेस इंजन के रूप में अजगर-साइकॉपग से अजगर-साइकॉपग 2 में परिवर्तित होने के बाद।

कोड समान रहता है, बस यह नहीं पता कि वे त्रुटियां कहां से हैं।


2
मैं उत्सुक हूं कि इस समस्या का अंतिम समाधान क्या था? मेरे पास यही समस्या है, लेकिन चूंकि मेरे होस्टिंग प्रदाता ने क्वेरी त्रुटियों को लॉग नहीं किया है इसलिए यह असंभव है कि अब तक यह पता लगाना कि क्या गलत है।
gerdemb

2
मैंने कैश बैकएंड के रूप में डेटाबेस तालिका का उपयोग करते हुए अंत में अपनी समस्या को बग पर ट्रैक किया। Django बग: code.djangoproject.com/ticket/11569 StackOverflow चर्चा: stackoverflow.com/questions/1189541/…
gerdemb

7
FYI करें यदि आप django के बिना psycopg2 का उपयोग कर रहे हैं, conn.rollback()(जहाँ con आपका कनेक्शन ऑब्जेक्ट है) तो त्रुटि को साफ़ कर देगा ताकि आप अन्य प्रश्नों को चला सकें
User

जवाबों:


177

यह तब होता है जब कोई क्वेरी किसी त्रुटि का उत्पादन करती है और जब आप पहले लेन-देन को वापस किए बिना किसी अन्य क्वेरी को चलाने का प्रयास करते हैं तो पोस्टग्रैज यही करता है। (आप इसे अपने डेटा को दूषित करने से बचाने के लिए एक सुरक्षा सुविधा के रूप में सोच सकते हैं।)

इसे ठीक करने के लिए, आप यह पता लगाना चाहेंगे कि उस कोड में जहां खराब क्वेरी को निष्पादित किया जा रहा है। यह आपके postgresql सर्वर में log_statement और log_min_error_statement विकल्पों का उपयोग करने के लिए सहायक हो सकता है।


समस्या यह है कि जब मैं अजगर-साइकोपग का उपयोग कर रहा था, तो ऐसी कोई त्रुटि नहीं उठाई गई। psycopg2 ने पोस्टग्रेज की बात करते हुए एक अलग तंत्र लागू किया है?
जैक

4
सर्वर से बात करने का तरीका शायद मायने नहीं रखता है, लेकिन यह संभव है कि आप जिस संस्करण का इस्तेमाल किसी भी तरह से पहले करते थे, वह नए संस्करण में नहीं होने के दौरान ऑटोक्मिट मोड पर डिफ़ॉल्ट हो। त्रुटि अभी भी हो सकती है, लेकिन आप इसे आसानी से याद कर सकते हैं। यह भी संभव है कि पुराने संस्करण के बाद से डेटा प्रकार रूपांतरण या कुछ और बदल गया हो। भले ही, सबसे अच्छा फिक्स खराब क्वेरी को ट्रैक करना है ताकि आप देख सकें कि इसमें क्या गलत है।
ʇs25oɈ

133

त्रुटि से छुटकारा पाने के लिए, अपना कोड तय करने के बाद अंतिम (त्रुटिपूर्ण) लेनदेन वापस करें :

from django.db import transaction
transaction.rollback()

त्रुटि होने से रोकने के लिए आप ट्राई-को छोड़कर का उपयोग कर सकते हैं:

from django.db import transaction, DatabaseError
try:
    a.save()
except DatabaseError:
    transaction.rollback()

संदर्भ: Django प्रलेखन


3
यह मुख्य मुद्दे को संबोधित करता है और आपको एक बयान के बाद पुनर्प्राप्त करने देता है जो गर्भपात के कारण होता है।
रिचवेल

यह, कोशिश / छोड़कर संयुक्त है।
टॉमवॉलर

3
IntegrityErrorआधार वर्ग का उपयोग और क्यों नहीं DatabaseError?
जोनाथन

किसी कारण से मुझे "सिवाय" खंड के रोलबैक को स्थानांतरित करना पड़ा। मैं .bulk_create () और नहीं .save () का उपयोग कर रहा था
nu everest


50

इसलिए, मैं इसी मुद्दे में भाग गया। मैं यहाँ जो समस्या आ रही थी वह यह थी कि मेरा डेटाबेस ठीक से सिंक नहीं किया गया था। साधारण समस्याएँ हमेशा सबसे अधिक परेशानी का कारण लगती हैं ...

टर्मिनल के भीतर, अपने ऐप डायरेक्टरी के भीतर से अपने django db को सिंक करने के लिए टाइप करें:

$ python manage.py syncdb

संपादित करें: ध्यान दें कि यदि आप django-south का उपयोग कर रहे हैं, तो '$ python manage.py migrate' कमांड चलाने से यह समस्या हल हो सकती है।

हैप्पी कोडिंग!


3
स्पष्ट बताते हुए अपवित्र। मैं इसे एक से अधिक अपवित्र नहीं दूंगा, क्योंकि शायद इसका जवाब नहीं मांगा गया था।
जेम्सन क्विन

5
मैंने इसे python manage.py migrate <app>... अपने सभी ऐप्स के लिए इसी तरह से तय किया है ।
क्लेटन

3
@ क्लेटन - आप नहीं कहते हैं, लेकिन मुझे लगता है कि आप उपयोग कर रहे हैं django-south - migrateकमांड django में नहीं बनाया गया है।
ग्रेग बॉल

@ ग्रेगबाल- यह सही है ... मैं दक्षिण-दक्षिण का उपयोग कर रहा हूं। निर्दिष्ट नहीं करने के लिए क्षमा करें।
क्लेटन

जब मैं syncdb कर रहा हूँ तो मुझे यह त्रुटि मिल रही है - मुझे लगता है कि यह उस क्रम के साथ करना है जो django तालिकाओं के माध्यम से जाता है।
स्टुअर्ट एक्सॉन

36

फ्लास्क में आपको बस लिखने की जरूरत है:

curs = conn.cursor()
curs.execute("ROLLBACK")
conn.commit()

पुनश्च प्रलेखन यहाँ जाता है https://www.postgresql.org/docs/9.4/static/sql-rollback.html


जब ज्यूपिटर नोटबुक में त्रुटि होती है तो यह समाधान भी बहुत मदद करता है।
स्किप्पी ले ग्रांड गौरौ

अच्छा लगा। इसने मेरी मदद की जुपिटर में
igorkf

34

मेरे अनुभव में, ये त्रुटियां इस तरह से होती हैं:

try:
    code_that_executes_bad_query()
    # transaction on DB is now bad
except:
    pass

# transaction on db is still bad
code_that_executes_working_query() # raises transaction error

दूसरी क्वेरी में कुछ भी गलत नहीं है, लेकिन जब से असली त्रुटि पकड़ी गई, दूसरी क्वेरी वह है जो (बहुत कम जानकारीपूर्ण) त्रुटि उठाती है।

संपादित करें: यह केवल तब होता है जब exceptक्लॉज पकड़ता है IntegrityError(या कोई अन्य निम्न स्तर डेटाबेस अपवाद), यदि आप कुछ ऐसा पकड़ते हैं जैसे DoesNotExistयह त्रुटि सामने नहीं आएगी, क्योंकि DoesNotExistलेनदेन को भ्रष्ट नहीं करता है।

यहाँ सबक कोशिश / छोड़कर / पास नहीं है।


16

मुझे लगता है कि PostgreSQL का उपयोग करते समय पैटर्न पुजारी उल्लेख इस मुद्दे का सामान्य कारण होने की अधिक संभावना है।

हालांकि मुझे लगता है कि पैटर्न के लिए मान्य उपयोग हैं और मुझे नहीं लगता कि यह मुद्दा हमेशा इससे बचने का एक कारण होना चाहिए। उदाहरण के लिए:

try:
    profile = user.get_profile()
except ObjectDoesNotExist:
    profile = make_default_profile_for_user(user)

do_something_with_profile(profile)

यदि आप इस पैटर्न के साथ ठीक महसूस करते हैं, लेकिन सभी जगह स्पष्ट लेन-देन से निपटने के कोड से बचना चाहते हैं तो आप ऑटोकॉमिट मोड (PostgreSQL 8.2+) को चालू करना चाहते हैं: https://docs.djangoproject.com/en/ देव / रेफरी / डेटाबेस / # autocommit मोड

DATABASES['default'] = {
    #.. you usual options...
    'OPTIONS': {
        'autocommit': True,
    }
}

यदि कोई महत्वपूर्ण प्रदर्शन विचार (या किसी अन्य प्रकार के) हैं तो मैं अनिश्चित हूं।


6

यदि आपको यह इंटरेक्टिव शेल में मिलता है और इसे जल्दी ठीक करने की आवश्यकता है, तो यह करें:

from django.db import connection
connection._rollback()

मूल रूप से इस जवाब में देखा गया


6

मुझे postgresटर्मिनल पर एक खराबी लेनदेन चलाते समय एक समान व्यवहार का सामना करना पड़ा । इसके बाद कुछ भी नहीं हुआ, जैसा कि databaseराज्य में है error। हालांकि, बस एक त्वरित समाधान के रूप में, यदि आप बचने के लिए खर्च कर सकते हैं rollback transaction। निम्नलिखित ने मेरे लिए चाल चली:

COMMIT;


मैं एक उत्तर में था, यह वही उत्तर है जिसकी मुझे तलाश थी।
18'18

5

मुझे सिलिमार की समस्या हो गई है। समाधान db ( manage.py syncdbया manage.py schemamigration --auto <table name>यदि आप दक्षिण का उपयोग करते हैं) को स्थानांतरित करना था ।


5

बस रोलबैक का उपयोग करें

उदाहरण कोड

try:
    cur.execute("CREATE TABLE IF NOT EXISTS test2 (id serial, qa text);")
except:
    cur.execute("rollback")
    cur.execute("CREATE TABLE IF NOT EXISTS test2 (id serial, qa text);")

1

मेरे पास यह त्रुटि भी थी, लेकिन यह एक और अधिक प्रासंगिक त्रुटि संदेश को चिह्नित कर रहा था जहां कोड 100 वर्णों में 125 वर्ण स्ट्रिंग को संग्रहीत करने का प्रयास कर रहा था:

DatabaseError: value too long for type character varying(100)

मुझे उपरोक्त संदेश को दिखाने के लिए कोड के माध्यम से डिबग करना था, अन्यथा यह प्रदर्शित करता है

DatabaseError: current transaction is aborted

1

@Priestc और @Sebastian के जवाब में, अगर आप ऐसा कुछ करते हैं तो क्या होगा?

try:
    conn.commit()
except:
    pass

cursor.execute( sql )
try: 
    return cursor.fetchall()
except: 
    conn.commit()
    return None

मैंने बस इस कोड की कोशिश की और यह संभव है कि किसी भी संभावित त्रुटियों के बारे में परवाह किए बिना चुपचाप विफल रहे, और जब क्वेरी अच्छी हो तो काम करना।


1

मेरा मानना ​​है कि @ अनुजगुप्त का उत्तर सही है। हालाँकि रोलबैक खुद एक अपवाद उठा सकता है जिसे आपको पकड़ना चाहिए और संभालना चाहिए:

from django.db import transaction, DatabaseError
try:
    a.save()
except DatabaseError:
    try:
        transaction.rollback()
    except transaction.TransactionManagementError:
        # Log or handle otherwise

यदि आप पाते हैं कि आप इस कोड को विभिन्न save()स्थानों पर लिख रहे हैं , तो आप अर्क-विधि कर सकते हैं:

import traceback
def try_rolling_back():
    try:
        transaction.rollback()
        log.warning('rolled back')  # example handling
    except transaction.TransactionManagementError:
        log.exception(traceback.format_exc())  # example handling

अंत में, आप एक डेकोरेटर का उपयोग करके इसे पूर्व निर्धारित कर सकते हैं जो उपयोग करने वाले तरीकों की रक्षा करता है save():

from functools import wraps
def try_rolling_back_on_exception(fn):
    @wraps(fn)
    def wrapped(*args, **kwargs):
        try:
            return fn(*args, **kwargs)
        except:
            traceback.print_exc()
            try_rolling_back()
    return wrapped

@try_rolling_back_on_exception
def some_saving_method():
    # ...
    model.save()
    # ...

यहां तक ​​कि अगर आप ऊपर के डेकोरेटर को लागू करते हैं, तब भी यह try_rolling_back()एक सुविधाजनक विधि के रूप में रखना सुविधाजनक है, अगर आपको इसे उन मामलों के लिए मैन्युअल रूप से उपयोग करने की आवश्यकता है जहां विशिष्ट हैंडलिंग की आवश्यकता होती है, और जेनेरिक डेकोरेटर हैंडलिंग पर्याप्त नहीं है।


1

यह मेरे लिए बहुत अजीब व्यवहार है। मुझे आश्चर्य है कि किसी ने भी बचत के बारे में नहीं सोचा। मेरे कोड में विफल होने वाले प्रश्न में अपेक्षित व्यवहार नहीं था:

from django.db import transaction
@transaction.commit_on_success
def update():
    skipped = 0
    for old_model in OldModel.objects.all():
        try:
            Model.objects.create(
                group_id=old_model.group_uuid,
                file_id=old_model.file_uuid,
            )
        except IntegrityError:
            skipped += 1
    return skipped

मैंने सेवपॉइंट का उपयोग करने के लिए इस तरह से कोड को बदल दिया है:

from django.db import transaction
@transaction.commit_on_success
def update():
    skipped = 0
    sid = transaction.savepoint()
    for old_model in OldModel.objects.all():
        try:
            Model.objects.create(
                group_id=old_model.group_uuid,
                file_id=old_model.file_uuid,
            )
        except IntegrityError:
            skipped += 1
            transaction.savepoint_rollback(sid)
        else:
            transaction.savepoint_commit(sid)
    return skipped

1

फ्लास्क खोल में, मुझे जो कुछ भी करने की ज़रूरत थी वह session.rollback()इस अतीत को प्राप्त करने के लिए था ।


1

मैं इस मुद्दे को पूरा कर चुका हूं, त्रुटि सामने आती है क्योंकि त्रुटि लेनदेन ठीक से समाप्त नहीं हुआ है, मुझे यहांpostgresql_transactions ट्रांजेक्शन कंट्रोल कमांड मिला

लेन-देन नियंत्रण

लेन-देन को नियंत्रित करने के लिए निम्न आदेशों का उपयोग किया जाता है

BEGIN TRANSACTION  To start a transaction.

COMMIT  To save the changes, alternatively you can use END TRANSACTION command.

ROLLBACK  To rollback the changes.

इसलिए मैं END TRANSACTIONइस तरह त्रुटि कोड, कोड को समाप्त करने के लिए उपयोग करें:

    for key_of_attribute, command in sql_command.items():
        cursor = connection.cursor()
        g_logger.info("execute command :%s" % (command))
        try:
            cursor.execute(command)
            rows = cursor.fetchall()
            g_logger.info("the command:%s result is :%s" % (command, rows))
            result_list[key_of_attribute] = rows
            g_logger.info("result_list is :%s" % (result_list))
        except Exception as e:
            cursor.execute('END TRANSACTION;')
            g_logger.info("error command :%s and error is :%s" % (command, e))
    return result_list

-6

आप "set_isolation_level (0)" के माध्यम से लेनदेन को अक्षम कर सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.