Tabellen sperren mit beliebigem ORM?
Verfasst: Samstag 3. Mai 2008, 16:40
Ich glaube, ich steh auf dem Schlauch. Ich möchte in einer Datenbank transaktionssicher prüfen, ob ein Datensatz vorhanden ist und ihn dann ändern oder aber einen neuen anlegen (und den dann ändern). In Python würde das so aussehen:
Für den naiven Ansatz, bräuchte ich diese Sequenz von SQL-Befehle:
Oder man nutzt aus, dass ein Update ein beliebiges `where` haben kann und zurückliefert, wie viele Zeilen betroffen waren. Dann schiebt man ein Insert hinterher, falls es 0 waren.
Wie auch immer, es sind mindestens zwei Befehle und dazwischen kann ein anderer Prozess Schaden anrichten, in dem er's auch versucht. Das ganze ist nicht atomar. Ich muss irgendwie die Tabelle in meiner Transaktion sperren.
Bitte nennt mir einen Python-ORM eurer Wahl und eine Lösung, wie und warum die funktioniert. Aus dunkler Vorzeit erinnere ich mich noch "select for update" als eine Lösung für das Problem, aber sowas ist Datenbank spezifisch und wo wäre der Sinn eines ORM, wenn ich nicht von SQL abstrahieren könnte?
Stefan
Code: Alles auswählen
activity = person.activities.find_or_create(kind='whatever')
activity.occurence += 1
Code: Alles auswählen
select * from activity where person_id=... and kind='whatever'
; falls es nicht existiert
insert into activity ('kind', 'occurences') values ('whatever', 0)
; bestimme jetzt last_insert_id oder wie das auch immer heißt
; ende von falls
update activity set occurence=occurence+1 where id=...
Wie auch immer, es sind mindestens zwei Befehle und dazwischen kann ein anderer Prozess Schaden anrichten, in dem er's auch versucht. Das ganze ist nicht atomar. Ich muss irgendwie die Tabelle in meiner Transaktion sperren.
Bitte nennt mir einen Python-ORM eurer Wahl und eine Lösung, wie und warum die funktioniert. Aus dunkler Vorzeit erinnere ich mich noch "select for update" als eine Lösung für das Problem, aber sowas ist Datenbank spezifisch und wo wäre der Sinn eines ORM, wenn ich nicht von SQL abstrahieren könnte?
Stefan