2009-09-18 6 views
1

app1.models.ModelOne이라는 모델을 저장하고 @commit_on_success으로 장식했다고 가정 해 봅시다. ModelOne.save()에 잡힌 모든 예외가 다시 제기됩니다. model_one_instance.save()에서 제대로 작동합니다.django의 중첩 트랜잭션?

그러나 app2에 일련 번호를 삽입하여 ModelOne에 삽입하고 실패 할 경우 모두 롤백해야합니다. 어떻게해야합니까?

app2.jobs.do_the_inserts@commit_on_success으로 꾸미는 것이 예상대로 작동하지 않습니다.

답변

3

중첩 트랜잭션은 데이터베이스에 따라 다르므로 이식성을 잃을 것입니다. 당신과 함께 아마, 임의의 SQL은 그래서 당신은 당신의 백엔드 데이터베이스가 사용하는 어떤으로 db.connection.cursor().execute()를 호출 할 수 있습니다 명령을 실행할 수

def save(commit=True): 
    if commit: 
    db.start_transaction() 
    try: 
     self.real_save() 
     db.commit_transaction() 
    except backend.DatabaseError, e: 
     db.rollback_transaction() 
     raise e 
    else: 
    self.real_save()  

을 그렇지 않은 : 그 필요하면, 좀 더 유연한 무엇인가에 대한 간단한 @commit_on_save을 변화하고 생각 하는데요 다른 백엔드에서는 아무것도하지 않으므로 로컬 테스트를 위해 sqlite를 사용할 수 있습니다.

앱 구조에 따라 savepoints을 사용할 수도 있습니다.

  • 세이브 포인트 커밋 실행
    • 시작 세이브 포인트
    • :
    • 시작 옵션 문을

      • 시작 트랜잭션
      • 수행 필수 명령 : 나는 같은 것을 할 몇 가지 유틸리티를 작성했습니다 또는 롤백
    • 더 강제적 SQL
  • +1

    여러분의 솔루션이 다른 문제를 해결하고 있다고 생각합니다. 예를 들어 foo()와 bar() 두 가지 메소드가 있다고 가정하고 둘 다 @commit_on_success로 꾸며져 있습니다.foo()가 bar()를 호출하면 언제 장고가 COMMIT를 데이터베이스에 보낼 것으로 예상합니까? 직감적 인 대답은 django가 foo() 메서드의 끝에 하나의 COMMIT를 발행한다고 생각합니다. 그러나 Django는 두 개의 COMMIT를 보냅니다. 하나는 bar() 끝에 있고, 다른 하나는 foo() 끝에 있습니다. 결과적으로 트랜잭션 데코레이터는 결코 중첩 될 수 없으며 매우 나쁜 일이 발생할 수 있습니다. –

    +0

    "데이터베이스 관련"이 아닌 중첩 된 트랜잭션은 PostgreSQL, SQLite 및 MySQL에서 같은 방식으로 작동하는 것처럼 보이는 SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT 명령을 통해 모든 주요 데이터베이스에서 사용할 수 있습니다. – intgr

    +0

    Django 내에서 savepoint는 1.4 이전에는 지원되지 않았습니다 (원래 게시물은 2009 년이었습니다). 그럼에도 불구하고, 당신은 여전히 ​​일반적인 InnoDB/MyISAM 토론을하고 있습니다. 이것은 당신이 기능을 사용해서는 안되지만 개발자는 지원이 가능하지 않으면 어떻게해야하는지 생각해야한다고 말하지 않습니다. –

    0

    DBMS 서버에 따라 중첩 트랜잭션은 전혀 지원되지 않을 수 있습니다. DBMS에서 중첩 된 트랜잭션을 올바르게 구현하는 것은 실제로 트랜잭션간에 잠금을 공유해야하기 때문에 실제로 어렵습니다.

    그러나 설명하는 내용은 중첩 된 트랜잭션처럼 들리지 않습니다. 장고가 XA 트랜잭션을 지원하는지는 모르겠지만 TP 모니터 구조와 XA 인식 DBMS (요즘 대부분)에서 설명 할 수 있습니다.

    플랫폼이 XA 트랜잭션을 지원하지 않는 경우 트랜잭션을 구조화하여 롤백하는 방법에 대한 레코드가 어딘가에 저장되도록해야합니다. Fowler의 Enterprise Application Architecture 패턴에 설명 된 'Unit of Work'패턴의 일부가 이러한 서브 시스템의 아키텍처를 시작하는 데 도움이 될 수 있습니다.

    +0

    DBMS 커밋은 PG 8.3이고; ORM 레이어를 통해이를 수행 할 수있는 방법이 있는지 궁금합니다. – ohnoes

    +0

    PG 8.3은 XA 트랜잭션을 지원하지만 장고가 지원하는지는 알 수 없습니다. 이 링크의 기사는 django의 트랜잭션 관리에 들어갑니다. http://blogs.gnome.org/jamesh/2008/09/01/transaction-management-in-django/ – ConcernedOfTunbridgeWells

    관련 문제