Dieser Typ von Haltbarkeit ist unmöglich wegen ACID, mit einer Verbindung. (d. h. dass ein verschachtelter Block festgeschrieben wird, während der äußere Block zurückgesetzt wird). Dies ist eine Konsequenz von ACID, kein Problem von Django. Stellen Sie sich eine Super-Datenbank vor und der Fall, dass die Tabelle B
einen Fremdschlüssel für die Tabelle A
enthält.
Wenn die innere "Transaktion" dauerhaft sein sollte, während die (äußere) Transaktion zurückgesetzt wird, dann wäre die Integrität gebrochen. Die Rollback-Operation muss immer so implementiert werden, dass sie niemals fehlschlagen kann. Daher würde keine Datenbank eine verschachtelte unabhängige Transaktion implementieren. Es wäre gegen den Grundsatz der Kausalität und die Integrität kann nach einem solchen selektiven Rollback nicht garantiert werden. Es ist auch gegen Atomizität.
Die Transaktion bezieht sich auf eine Datenbankverbindung. Wenn Sie zwei Verbindungen erstellen, werden zwei unabhängige Transaktionen erstellt. Eine Verbindung erkennt nicht festgeschriebene Zeilen anderer Transaktionen (es ist möglich, diese Isolationsstufe festzulegen, aber es hängt vom Datenbank-Back-End ab) und keine Fremdschlüssel können erstellt werden und die Integrität wird nach dem Rollback durch die Datenbank beibehalten Backend-Design.
Django unterstützt mehrere Datenbanken, daher mehrere Verbindungen.
# no ATOMIC_REQUESTS should be set for "other_db" in DATABASES
@transaction.atomic # atomic for the database "default"
def my_view():
with atomic(): # or set atomic() here, for the database "default"
some_code()
with atomic("other_db"):
row = OtherModel.objects.using("other_db").create(**kwargs)
raise DatabaseError
Die Daten in "other_db" bleibt festgelegt.
Es ist wahrscheinlich in Django möglich, einen Trick mit zwei Verbindungen zur gleichen Datenbank zu erstellen, wie es zwei Datenbanken mit einigen Datenbank-Backends wären, aber ich bin sicher, dass es ungetestet ist, es würde zu Fehlern neigen, Bei Problemen mit Migrationen ist eine größere Belastung durch das Datenbank-Backend erforderlich, das bei jeder Anforderung echte parallele Transaktionen erstellen muss und nicht optimiert werden kann. Es ist besser, zwei echte Datenbanken zu verwenden oder den Code zu reorganisieren.
Die Einstellung DATABASE_ROUTERS ist sehr nützlich, aber ich bin mir noch nicht sicher, ob Sie an mehreren Verbindungen interessiert sind.
Ich konnte die Antwort auf meine Frage in Ihrem Text nicht finden. Sie sagen, ich muss sicherstellen, dass der äußere Atomblock festgeschrieben wird. Ja das stimmt. Wie macht man das im Django? – guettli
@guettli Ich habe meine Antwort aktualisiert. Dafür gibt es keine API. Die einzige Möglichkeit, dies zu erreichen, besteht darin, sicherzustellen, dass der Code in der Transaktion ohne Fehler beendet wird. – knbk
@guettli, wenn Sie Low-Level-Transaktionsverwaltung in Django tun möchten, können Sie verwenden Sie das 'transaction' Paket direkt. Für ein Beispiel können Sie https://github.com/2ps/djenga/blob/master/djenga/db/nested_transactions.py sehen, was ich zurückgeschrieben habe, als django verschachtelte Transaktionen in mysql nicht unterstützt hat. – 2ps