ডাটাবেসএরর: বর্তমান লেনদেনটি বাতিল হয়ে গেছে, লেনদেন অবরুদ্ধ হওয়ার অবধি কমান্ডগুলি উপেক্ষা করা হবে?


252

আমি বার্তাটি দিয়ে অনেক ত্রুটি পেয়েছি:

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

জ্যাঙ্গো প্রকল্পের ডেটাবেস ইঞ্জিন হিসাবে পাইথন-সাইকোপগ থেকে পাইথন-সাইকোপজি 2 এ পরিবর্তন করার পরে।

কোডটি একইরূপে রয়েছে, কেবল ত্রুটিগুলি কোথা থেকে এসেছে তা জানেন না।


2
আমি কৌতুহল করছি এই সমস্যার জন্য আপনার চূড়ান্ত সমাধানটি কী ছিল? আমার এই একই সমস্যা রয়েছে, তবে যেহেতু আমার হোস্টিং সরবরাহকারী কোয়েরি ত্রুটিগুলি লগ না করে এখন পর্যন্ত কী ভুল হচ্ছে তা নির্ধারণ করা অসম্ভব।
জার্মডেম্ব

2
ক্যাশে ব্যাকএন্ড হিসাবে ডেটাবেস টেবিল ব্যবহার করার সময় অবশেষে আমি আমার সমস্যাটি একটি বাগে সন্ধান করেছি। জ্যাঙ্গো বাগ: code.djangoproject.com/ticket/11569 Stackoverflow আলোচনা: stackoverflow.com/questions/1189541/...
gerdemb

7
এফওয়াইআই যদি আপনি কেবল জ্যাঙ্গো ছাড়াই সাইকোপজি 2 ব্যবহার করেন, conn.rollback()(যেখানে সংযোগটি আপনার সংযোগের বস্তু) ত্রুটিটি সাফ করবে যাতে আপনি অন্যান্য অনুসন্ধান চালাতে পারেন
ব্যবহারকারী

উত্তর:


177

পোস্টরিগ্রেসগুলি যখন এমন হয় যখন কোনও ক্যোয়ারী একটি ত্রুটি তৈরি করে এবং আপনি প্রথমে লেনদেনটি পিছনে না ফেলেই অন্য কোয়েরি চালানোর চেষ্টা করেন। (আপনি আপনার ডেটাটি দূষিত করা থেকে বাঁচানোর জন্য এটিকে একটি সুরক্ষা বৈশিষ্ট্য হিসাবে ভাবতে পারেন))

এটি ঠিক করার জন্য, আপনি কোডটি খুঁজে বের করতে চাইবেন যে কোডটিতে খারাপ কোয়েরি কার্যকর করা হচ্ছে। আপনার পোস্টগ্রিস্কল সার্ভারে লগ_স্টেটমেন্ট এবং লগ_মিনি_অরার_স্টেটমেন্ট বিকল্পগুলি ব্যবহার করা সহায়ক হতে পারে ।


সমস্যাটি যখন আমি পাইথন-সাইকোপগ ব্যবহার করছিলাম তখন এ জাতীয় কোনও ত্রুটি উত্থাপিত হয়নি। সাইকোপজি 2 পোস্টগ্রাজের সাথে কথা বলার জন্য একটি ভিন্ন পদ্ধতি প্রয়োগ করে?
জ্যাক

4
সার্ভারের সাথে কথা বলার পদ্ধতিটি সম্ভবত কিছু যায় আসে না, তবে এটি সম্ভবত সম্ভব যে আপনি যে সংস্করণটি ব্যবহার করেছিলেন তার আগে কোনওরকম ডিফল্ট করা হয়েছে অটোমোম্যাট মোডে নতুন সংস্করণটি না থাকলে। ত্রুটিটি এখনও ঘটতে পারে তবে আপনি এটি সহজেই এড়াতে পারতেন। পুরানো সংস্করণ থেকে ডেটা ধরণের রূপান্তর বা অন্য কিছু পরিবর্তিত হয়েছে এটিও সম্ভব। নির্বিশেষে, সর্বোত্তম ফিক্সটি হল খারাপ ক্যোয়ারীটি সন্ধান করা যাতে আপনি দেখতে পাচ্ছেন যে এতে কী আছে।
әɹsәɹoɈ

133

ত্রুটি থেকে মুক্তি পেতে, আপনার কোড ঠিক করার পরে শেষ (ভ্রান্ত) লেনদেনটি আবার রোল করুন :

from django.db import transaction
transaction.rollback()

ত্রুটি দেখা দিতে বাধা দিতে আপনি চেষ্টা-ব্যবহার ব্যতীত ব্যবহার করতে পারেন:

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

তথ্যসূত্র: জ্যাঙ্গো ডকুমেন্টেশন


3
এটি মূল সমস্যাটিকে সম্বোধন করে এবং বাতিল হওয়া লেনদেনের কারণ হিসাবে একটি বিবৃতি দেওয়ার পরে আপনাকে পুনরুদ্ধার করতে দেয়।
রিচভেল

এটি চেষ্টা করে / বাদে মিলিত।
টমওয়লবার

3
কেন IntegrityErrorবেস ক্লাস ব্যবহার এবং না DatabaseError?
জোনাথন

কিছু কারণে আমাকে "বাদে" বিভাগের বাইরে রোলব্যাকটি সরিয়ে নিতে হয়েছিল। আমি .bulk_create () এবং .save না () ব্যবহার করছিলেন
নিউ এভারেস্ট

এই নিম্নলিখিত পর জ্যাঙ্গো 1.4.16 সঙ্গে কাজ stackoverflow.com/a/15753000/573034
পাওলো

50

সুতরাং, আমি এই একই সমস্যা মধ্যে দৌড়ে। আমার যে সমস্যাটি এখানে ছিল তা হ'ল আমার ডাটাবেসটি সঠিকভাবে সিঙ্ক হয়নি। সাধারণ সমস্যাগুলি সর্বদা সবচেয়ে বিরক্তির কারণ বলে মনে হয় ...

আপনার অ্যাপ্লিকেশন ডিরেক্টরি থেকে টার্মিনালের মধ্যে আপনার জ্যাঙ্গো ডিবি সিঙ্ক করতে টাইপ করুন:

$ python manage.py syncdb

সম্পাদনা: নোট করুন যে আপনি যদি জাঙ্গো-দক্ষিণ ব্যবহার করছেন, '$ পাইথন ম্যানেজ.পি মাইগ্রেট' কমান্ড চালানোও এই সমস্যাটি সমাধান করতে পারে।

শুভ কোডিং!


3
সুস্পষ্টভাবে উল্লেখ করার জন্য উত্সাহিত আমি এটিকে একাধিক উত্সাহ দিতে পারব না কারণ এটি সম্ভবত উত্তর চেয়েছিল না।
জেমসন কুইন

5
আমার python manage.py migrate <app>সমস্ত অ্যাপ্লিকেশনের জন্য আমি এটি একইভাবে স্থির করেছি ।
ক্লেটন

3
@ ক্লেটন - আপনি বলবেন না তবে আমি ধরে নিচ্ছি আপনি ব্যবহার করছেন django-south - migrateকমান্ডটি জাঙ্গোতে তৈরি করা হয়নি।
গ্রেগ বল

@ গ্রেগবাল- এটি সঠিক ... আমি জাঙ্গো-দক্ষিণ ব্যবহার করছি। নির্দিষ্ট না করার জন্য দুঃখিত।
ক্লেটন

সিঙ্কডিবি করার সময় আমি এই ত্রুটিটি পাচ্ছি - আমি মনে করি এটি জাজো টেবিলগুলির মধ্য দিয়ে যায় এমন ক্রমটি করতে হবে।
স্টুয়ার্ট অ্যাকসন

35

ফ্লাস্কে আপনাকে কেবল লিখতে হবে:

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

পিএস ডকুমেন্টেশন এখানে যায় https://www.postgresql.org/docs/9.4/static/sql-rolback.html


একটি বৃহত্তর নোটবুকটিতে ত্রুটি দেখা দিলে এই সমাধানটিও বেশ সহায়ক।
স্কিপি লে গ্র্যান্ড গৌরো

খুশী হলাম। এটি আমাকে
জুপিটারে

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

আমার মনে হয় পোস্টগ্রের এসকিউএল ব্যবহার করার সময় প্যাটার্নের পুরোহিত উল্লেখ করেছেন যে এই সমস্যাটির স্বাভাবিক কারণ হওয়ার সম্ভাবনা বেশি।

তবে আমি অনুভব করি যে প্যাটার্নটির বৈধ ব্যবহার রয়েছে এবং আমি মনে করি না যে এই সমস্যাটি সর্বদা এড়াতে হবে। উদাহরণ স্বরূপ:

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/ দেব / ref & / ডাটাবেস / # autocommit-মোড

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

গুরুত্বপূর্ণ পারফরম্যান্স বিবেচনা (বা অন্য কোনও ধরণের) থাকলে আমি নিশ্চিত নই।


6

ইন্টারেক্টিভ শেলের সাথে সাথে আপনি যদি এটি পান এবং দ্রুত সমাধানের প্রয়োজন হয় তবে এটি করুন:

from django.db import connection
connection._rollback()

মূলত এই উত্তরে দেখা গেছে


6

postgresটার্মিনালে কোনও ত্রুটিযুক্ত লেনদেন চালানোর সময় আমি একইরকম আচরণের মুখোমুখি হয়েছি । কিছুই পরে মাধ্যমে গিয়েছিলাম হিসাবে databaseএকটি রাষ্ট্র হয় error। যাইহোক, শুধু একটি দ্রুত ফিক্স হিসাবে, আপনি এড়াতে সামর্থ যদি rollback transaction। নিম্নলিখিতটি আমার জন্য কৌশলটি করেছে:

COMMIT;


আমি একটি প্রতিবেদনে ছিলাম, এটি ঠিক উত্তর যা আমি সন্ধান করছিলাম।

5

আমি সিলিমার সমস্যা পেয়েছি। সমাধানটি ছিল ডিবি স্থানান্তর ( 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

@ প্রাইস্টক এবং @ সেবাস্তিয়ানের প্রতিক্রিয়াতে, আপনি যদি এই জাতীয় কিছু করেন তবে?

try:
    conn.commit()
except:
    pass

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

আমি এই কোডটি কেবল চেষ্টা করেছি এবং মনে হচ্ছে এটি কোনও কার্যকর ত্রুটির বিষয়ে চিন্তা না করে নিঃশব্দে ব্যর্থ হয়েছে এবং যখন অনুসন্ধানটি ভাল হবে তখন কাজ করছি working


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)" এর মাধ্যমে লেনদেন অক্ষম করতে পারবেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.