itsource

DatabaseError: 현재 트랜잭션이 중단되었습니다. 트랜잭션 블록이 끝날 때까지 명령이 무시됩니까?

mycopycode 2022. 9. 23. 00:17
반응형

DatabaseError: 현재 트랜잭션이 중단되었습니다. 트랜잭션 블록이 끝날 때까지 명령이 무시됩니까?

다음 메시지에서 오류가 많이 발생했습니다.

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

이후 Django 프로젝트의 데이터베이스 엔진으로 python-sycopg에서 python-sycopg2로 변경되었습니다.

코드는 그대로입니다만, 에러의 출처를 알 수 없습니다.

이것은 쿼리에서 오류가 발생하고 트랜잭션을 롤백하지 않고 다른 쿼리를 실행하려고 할 때 postgres가 수행하는 작업입니다.(데이터를 손상시키지 않기 위한 안전 기능으로 생각할 수 있습니다.

이 문제를 해결하려면 코드 내에서 잘못된 쿼리가 실행되고 있는 위치를 파악해야 합니다.postgresql 서버에서 log_statementlog_min_error_statement 옵션을 사용하면 도움이 될 수 있습니다.

오류를 제거하려면 코드를 수정한 후 마지막(오류) 트랜잭션을 롤백하십시오.

from django.db import transaction
transaction.rollback()

오류 발생을 방지하기 위해 try-except를 사용할 수 있습니다.

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

장고 매뉴얼을 참조하십시오.

플라스크에는 다음과 같이 적기만 하면 됩니다.

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

P.S. 매뉴얼은 https://www.postgresql.org/docs/9.4/static/sql-rollback.html에 있습니다.

그래서 저도 같은 문제에 부딪혔어요.여기서 발생한 문제는 데이터베이스가 제대로 동기화되지 않았다는 것입니다.간단한 문제가 항상 가장 큰 불안을 야기하는 것 같다...

django db를 동기화하려면 앱 디렉토리의 터미널에 다음과 같이 입력합니다.

$ python manage.py syncdb

편집: django-south를 사용하는 경우 $python manage를 실행합니다.py migrate' 명령을 사용하면 이 문제가 해결될 수도 있습니다.

해피 코딩!

제 경험상 다음과 같은 오류가 발생합니다.

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

두 번째 쿼리는 문제가 없지만 실제 오류가 검출되었기 때문에 두 번째 쿼리는 (정보가 훨씬 적은) 오류를 발생시키는 쿼리입니다.

edit: 이것은, 다음의 경우에 한해 발생합니다.except " "를 포착합니다.IntegrityError 기타 예외와 같은 .DoesNotExist. 이 에러는 발생하지 않습니다.왜냐하면DoesNotExist트랜잭션을 손상시키지 않습니다.

여기서의 교훈은 시도/제외/합격하지 말라는 것이다.

Postgre를 사용할 때 priestc가 언급한 패턴이 이 문제의 일반적인 원인일 가능성이 높다고 생각합니다.SQL.

하지만 패턴에 대한 유효한 용도가 있다고 생각하며, 이 문제가 항상 회피할 이유는 아니라고 생각합니다.예를 들어 다음과 같습니다.

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

do_something_with_profile(profile)

이 패턴에 문제가 없다고 느끼지만 명시적인 트랜잭션 처리 코드를 사용하지 않으려면 자동 커밋 모드를 켜는 것을 고려해 보십시오(Postgre).SQL 8.2+) https://docs.djangoproject.com/en/dev/ref/databases/ #syslog Commit 모드

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

중요한 퍼포먼스 고려사항(또는 다른 타입)이 있는지 잘 모르겠습니다.

롤백만 사용

코드 예시

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);")

뛰기만 하면 된다.

rollback;

포스트그레에서SQL이면 끝!

인터랙티브셸에서 이 문제가 발생하여 빠른 수정이 필요한 경우 다음 절차를 수행합니다.

from django.db import connection
connection._rollback()

원래답변에서 볼 수 있는

postgres터미널을 클릭합니다.아무 일도 일어나지 .database의 상태에 error 응급처치를 할수 한, 수 , 가능한 한 빨리 해결하도록 하겠습니다rollback transaction하다

COMMIT;

여기서도 비슷한 오류가 발생했습니다.이 링크에서 답을 찾았습니다.https://www.postgresqltutorial.com/postgresql-python/transaction/

client = PsqlConnection(config)
connection = client.connection
cursor = client.cursor

try:
   for query in list_of_querys:
      #query format => "INSERT INTO <database.table> VALUES (<values>)"
      cursor.execute(query)
      connection.commit()
except BaseException as e:
   connection.rollback()

postgresql로 전송한 다음 쿼리를 실행해도 오류가 반환되지 않습니다.

해결방법은 db(db)하는 이었습니다.manage.py syncdb ★★★★★★★★★★★★★★★★★」manage.py schemamigration --auto <table name>(「」「」 「」)

플라스크 쉘에서 내가 할 일은session.rollback()이 일을 이겨내기 위해서요

이 거래가 제대로 .오류 트랜잭션이 올바르게 종료되지 않았기 때문에 에러가 발생하고 있습니다.postgresql_transactionsTransaction Control 명령어(여기)

트랜잭션 제어

트랜잭션을 제어하려면 다음 명령을 사용합니다.

BEGIN TRANSACTION − To start a transaction.

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

ROLLBACK − To rollback the changes.

나는 ㅇㅇㅇㅇㅇㅇ를 사용한다.END TRANSACTIONTRANSTACTION을 사용하다

    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

저도 방금 이 오류가 발생했는데, 코드가 125자 문자열을 100자 열에 저장하려고 하는 다른 관련 오류 메시지를 마스킹하고 있었습니다.

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

위의 메시지가 표시되도록 코드를 디버깅해야 합니다.그렇지 않으면 이 메시지가 표시됩니다.

DatabaseError: current transaction is aborted

@priestc와 @Sebastian에 대한 응답으로, 이런 것을 하면 어떻게 될까요?

try:
    conn.commit()
except:
    pass

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

방금 이 코드를 시험해 봤는데, 동작하고 있는 것 같습니다.오류를 신경 쓰지 않고 조용히 실패해, 쿼리가 잘 되면 동작합니다.

나는 @anujGupta의 답이 맞다고 믿는다.단, 롤백 자체에서 예외가 발생할 수 있으므로 이를 포착하여 처리해야 합니다.

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()특정 취급이 필요한 경우, 일반적인 데코레이터 취급만으로는 불충분한 경우 추출된 방법으로 사용할 수 있습니다.

이것은 나에게 매우 이상한 행동이다.아무도 세이브포인트를 생각하지 않았다니 놀랍다.내 코드 실패 쿼리는 예상되는 동작이었습니다.

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

Save Point를 사용하도록 코드를 변경했습니다.

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

python package psycopg2를 사용하고 있는데 문의 중에 이 오류가 발생했습니다.쿼리, 실행 기능만 계속 실행했는데 다시 연결(아래 그림)을 실행하면 문제가 해결되었습니다.스크립트 위에 있는 것, 즉 접속을 다시 실행합니다.위에서 말한 것처럼 연결이 끊겼거나 동기화가 안 된 것 같습니다.

connection = psycopg2.connect(user = "##",
        password = "##",
        host = "##",
        port = "##",
        database = "##")
cursor = connection.cursor()

이는 이전 쿼리가 일시 중단되거나 롤백될 때까지 다른 쿼리를 실행할 수 없는 잘못된 SQL 실행 문제입니다.

PgAdmin4-4.24에는 롤백 옵션이 있어 이를 사용해 볼 수 있습니다.

여기에 이미지 설명 입력

set_disable_level(0)을 통해 트랜잭션을 비활성화할 수 있습니다.

언급URL : https://stackoverflow.com/questions/2979369/databaseerror-current-transaction-is-aborted-commands-ignored-until-end-of-tra

반응형