PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PostgreSQL: Transaktion



mike
10-02-2004, 12:09
Hi
Ich schreibe mit Hilfe der libq (C/C++) ein Angebotsverwaltungsprogramm. Ich will, dass während des Erstellungsprozesses andere User das Angebot nicht bearbeiten können.
Also hab ich beim Client folgendes gemacht:
PQexec(conn, "BEGIN;");
PQexec(conn, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;");
Als nächstes füge ich die KundenID ein:
...INSERT INTO tblangebote (kundenid) VALUES(%i);
PQexec(conn, "COMMIT;");
PQexec(conn, "BEGIN;");
Nun hab ich schon mein erstes Problem *g*
Ich hole direkt nach dem Einfügen mit "unsigned oid = PQoidValue(res);" die letzte oid, um den Datensatz anschließend zu sperren.

Was ist, wenn zu dem gleichen Zeitpunkt ein anderer User einen Datensatz einfügt und ich bekomme seine oid? :confused:

Als nächstes sperre ich den Datensatz:
SELECT * FROM tblangebote WHERE angeboteid=%i FOR UPDATE;

Nun habe ich mit psql den Datensatz updaten wollen - das funktioniert natürlich nicht, da er ja gesperrt ist. Nur das blöde ist, dass er "hängt". psql wartet solange, bis ich die Transaktion commited habe.

Kann man das irgendwie gleich mit einem Error abbrechen?

Danke im Voraus!!!
mfg

Christoph
10-02-2004, 19:21
Wenn Du im Transaction Level SERIALAZABLE bist, dann brauchst du nicht zu sperren mit SELECT FOR UPDATE. PostgreSQL kümmert sich automatisch um die Konsistenzsicherung. Allerdings kannst Du irgendwann eine "cannot serialize" Fehler bekommen (bei SELECT FOR UPDATE kann statt dessen ein "deadlock detected" Fheler kommen).

Dazu gibt es einen sehr guten Vortrag von Tom Lane:
http://www.sai.msu.su/~megera/postgres/gist/papers/concurrency/concurrency.pdf

mike
10-02-2004, 21:05
Cool Danke. RedHat hat allgemein viel Postgre Docus. Find ich gut ;) Werde es dann einfach mit nem simplen BEGIN COMMIT lösen.

Danke nochmals, mfg