Wednesday, August 6, 2008

[pgsql-de-allgemein] Re: [pgsql-de-allgemein] Re: [pgsql-de-allgemein] RE: [pgsql-de-allgemein] In Funktion prüfen ob Zeile existiert

Hi,

Bernd Helmle wrote:
> In PostgreSQL sollte es eigentlich auf Datenbankebene keine Unterschiede
> zu beiden geben, geschwindigkeitsmäßig.

Das sehe ich anders: waehrend Du mit SELECT FOR UPDATE ein tuple
'lockst', auch wenn dies in der gossen Mehrheit der Faelle nicht noetig
waere (pessimistic locking: um sicher zu gehen, dass nix schief geht,
sperrst Du lieber zuviel als zu wenig) entdeckt der SERIALIZABLE
ISOLATION LEVEL Konflikte auch ohne diese Locks (optimistic locking: nur
die absolut notwendigen locks werden gesperrt).

Solange also nur wenige Konflikte wegen Nebenlaeufigkeit zu erwarten
sind - was fuer die allermeisten Applikationen zutreffen duerft - dann
ist der SERIALIZABLE mode also performanter.

> Ich weiß, das SAVEPOINTs Shared
> Memory "fressen", aber "fressen" ist relativ.

Uh.. ich wuerde das ganz ohne SAVEPOINT machen...

> Wer sowas tausendfach in
> einer Schleife macht, muß damit rechnen, irgendwann an die Grenzen der
> Ressourcen zu stoßen.

Huh? Wenn Du einen kompletten ROLLBACK der Transaktion machst, dann
werden die Resources fuer die SAVEPOINTs freigegeben. Zudem: wieso
tausendfach? Erwartest Du wirklich so viele Konflikte?

> Dies innerhalb der Datenbank zu kapseln ist
> deutlich schöner als mit fehlerträchtigen Retry-Loops der Applikation zu
> spielen.

Schoener? Keine Ahnung, auf jeden Fall weniger solide. Die Retry-Loop
ist jedenfalls die empfohlene Vorgehensweise, siehe [1]. Sie ist auch
fuer den READ COMMITTED ISOLATION LEVEL noetig, weil auch dort Deadlocks
auftreten koennen. (Ausser Du stellst sicher, dass Deine Transaktionen
sich nie gegenseitig behindern, sondern die Locks immer in derselben
Reihenfolge sperren. Zugegeben, fuer einfache Anwendungen ist das meist
der Fall). Ganz zu schweigen von weiteren moeglichen Fehlerquellen.

Ueblich ist das leider nicht. Gerade z.B. Web-Anwendungen verlagern die
Retry-Loop gerne zum User und vertrauen darauf, dass wenn diesem
seltenerweise ein unverstaendlicher Datenbank Fehler entgegen knallt,
dieser einfach nochmals probieren wird. Funktioniert auch.

Wieso Retry-Loops fehlertraechtig sein sollen ist mir schleierhaft, die
Loop dient ja genau dazu, Fehler abzufangen und entsprechend darauf zu
reagieren. Natuerlich solltest Du die Endlosschleife vermeiden, aber das
versteht sich ja wohl von selbst.

Gruesse

Markus Wanner

[1]: Tom Lane: PostgreSQL Concurrency Issues:
http://www.postgresql.org/files/developer/concurrency.pdf

--
Sent via pgsql-de-allgemein mailing list (pgsql-de-allgemein@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-de-allgemein

No comments: