In Funktion prüfen ob Zeile existiert

In Funktion prüfen ob Zeile existiert

am 31.07.2008 23:27:22 von Oliver Baer

Hallo,

ich habe hier einen teil einer Postgresfunktion welche eine Tabelle updat=
ed.

...
LOOP
-- RAISE NOTICE 'notify_id %', asset_notify.notify_id;
-- RAISE NOTICE 'asset_id %', NEW.asset_id;
-- RAISE NOTICE 'label_id %', asset_notify.label_id;
INSERT INTO asset.asset_labels (label_id, asset_id, state, lo=
gin_id) values (asset_notify.label_id, NEW.asset_id, -2, asset_notify.log=
in_id);
END LOOP;
...

Das problem welches ich gerade habe ist folgendes.

Es kann sein das mit das der insert auf die tabelle fehlschlägt weil=20
dort schon etwas drinsteht (unique auf asset_id, label_id). Das würde=20
ich gerne abfangen, das heisst wenn der insert fehlschlägt soll er ein=20
update machen.

Leider kenne ich mit Funktionen in Postgres nicht so gut aus, vielleicht=20
hilft mir ja hier jemand auf die sprünge...

Ich stelle mir einfach eine IF abfrage vor:

IF insert schlägt fehl THEN update ...

Danke schonmal,

Oli

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

Re: In Funktion prüfen ob Zeile existiert

am 03.08.2008 23:23:59 von muellerrobert

MjAwOC83LzMxLCBPbGl2ZXIgQmFlciA8b2xpdmVyLmJhZXJAcHJlc3N3YXRj
aC5kZT46Cj4gSGFsbG8sCj4KPiBpY2ggaGFiZSBoaWVyIGVpbmVuIHRlaWwg
ZWluZXIgUG9zdGdyZXNmdW5rdGlvbiB3ZWxjaGUgZWluZSBUYWJlbGxlIHVw
ZGF0ZWQuCj4KPiAgICAgICAuLi4KPiAJTE9PUAo+IC0tICAgICAgICAgICAg
UkFJU0UgTk9USUNFICdub3RpZnlfaWQgJScsIGFzc2V0X25vdGlmeS5ub3Rp
ZnlfaWQ7Cj4gLS0gICAgICAgICAgICBSQUlTRSBOT1RJQ0UgJ2Fzc2V0X2lk
ICUnLCBORVcuYXNzZXRfaWQ7Cj4gLS0gICAgICAgICAgICBSQUlTRSBOT1RJ
Q0UgJ2xhYmVsX2lkICUnLCBhc3NldF9ub3RpZnkubGFiZWxfaWQ7Cj4gICAg
ICAgICAgICAgSU5TRVJUIElOVE8gYXNzZXQuYXNzZXRfbGFiZWxzIChsYWJl
bF9pZCwgYXNzZXRfaWQsIHN0YXRlLAo+IGxvZ2luX2lkKSB2YWx1ZXMgKGFz
c2V0X25vdGlmeS5sYWJlbF9pZCwgTkVXLmFzc2V0X2lkLCAtMiwKPiBhc3Nl
dF9ub3RpZnkubG9naW5faWQpOwo+ICAgICAgICAgRU5EIExPT1A7Cj4gICAg
ICAgLi4uCj4KPiBEYXMgcHJvYmxlbSB3ZWxjaGVzIGljaCBnZXJhZGUgaGFi
ZSBpc3QgZm9sZ2VuZGVzLgo+Cj4gRXMga2FubiBzZWluIGRhcyBtaXQgZGFz
IGRlciBpbnNlcnQgYXVmIGRpZSB0YWJlbGxlIGZlaGxzY2hsw6RndCB3ZWls
Cj4gZG9ydCBzY2hvbiBldHdhcyBkcmluc3RlaHQgKHVuaXF1ZSBhdWYgYXNz
ZXRfaWQsIGxhYmVsX2lkKS4gRGFzIHfDvHJkZQo+IGljaCBnZXJuZSBhYmZh
bmdlbiwgZGFzIGhlaXNzdCB3ZW5uIGRlciBpbnNlcnQgZmVobHNjaGzDpGd0
IHNvbGwgZXIgZWluCj4gdXBkYXRlIG1hY2hlbi4KPgo+IExlaWRlciBrZW5u
ZSBpY2ggbWl0IEZ1bmt0aW9uZW4gaW4gUG9zdGdyZXMgbmljaHQgc28gZ3V0
IGF1cywgdmllbGxlaWNodAo+IGhpbGZ0IG1pciBqYSBoaWVyIGplbWFuZCBh
dWYgZGllIHNwcsO8bmdlLi4uCj4KPiBJY2ggc3RlbGxlIG1pciBlaW5mYWNo
IGVpbmUgSUYgYWJmcmFnZSB2b3I6Cj4KPiBJRiBpbnNlcnQgc2NobMOkZ3Qg
ZmVobCBUSEVOIHVwZGF0ZSAuLi4KPgo+IERhbmtlIHNjaG9ubWFsLAoKTWly
IHfDvHJkZSBkYSBhbHMgZXJzdGVzIEV4Y2VwdGlvbnMgZWluZmFsbGVuOgpo
dHRwOi8vd3d3LnBvc3RncmVzcWwub3JnL2RvY3MvOC4zL2ludGVyYWN0aXZl
L3BscGdzcWwtY29udHJvbC1zdHJ1Y3R1cmVzLmh0bWwjUExQR1NRTC1FUlJP
Ui1UUkFQUElORwoKVmllbGxlaWNodCBoaWxmdCBEaXIgZGFzIGphIHNjaG9u
IG1hbCB3ZWl0ZXIuCgo+Cj4gT2xpCj4KUm9iZXJ0CgotLSAKU2VudCB2aWEg
cGdzcWwtZGUtYWxsZ2VtZWluIG1haWxpbmcgbGlzdCAocGdzcWwtZGUtYWxs
Z2VtZWluQHBvc3RncmVzcWwub3JnKQpUbyBtYWtlIGNoYW5nZXMgdG8geW91
ciBzdWJzY3JpcHRpb246Cmh0dHA6Ly93d3cucG9zdGdyZXNxbC5vcmcvbWFp
bHByZWYvcGdzcWwtZGUtYWxsZ2VtZWluCg==

Re: In Funktion prüfenobZeile existiert

am 04.08.2008 00:00:49 von Tim Landscheidt

Oliver Baer wrote:

> [...]
> Ich stelle mir einfach eine IF abfrage vor:

> IF insert schlägt fehl THEN update ...

Aufgrund einer Abneigung gegen Exceptions schreibe ich so
etwas meist in der Form:

| UPDATE Table SET Something =3D 'something' WHERE ID =3D 'id';
| IF NOT FOUND THEN
| INSERT INTO Table (ID, Something) VALUES ('id', 'something');
| END IF;

Tim

--=20
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

Re: In Funktion prüfen ob Zeile existiert

am 06.08.2008 00:33:39 von Bernd Helmle

--On Sonntag, August 03, 2008 22:00:49 +0000 Tim Landscheidt=20
wrote:

> Aufgrund einer Abneigung gegen Exceptions schreibe ich so
> etwas meist in der Form:
>
>| UPDATE Table SET Something =3D 'something' WHERE ID =3D 'id';
>| IF NOT FOUND THEN
>| INSERT INTO Table (ID, Something) VALUES ('id', 'something');
>| END IF;

....was aber bei Nebenläufigkeit ohne explizites Locking zu Race Condition=
s=20
führt. Was ist das Problem an Exceptions?

--=20
Thanks

Bernd

--=20
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

RE: [pgsql-de-allgemein] In Funktion prüfen ob Zei

am 06.08.2008 09:22:53 von Albe Laurenz

Bernd Helmle schrieb:
> > Aufgrund einer Abneigung gegen Exceptions schreibe ich so
> > etwas meist in der Form:
> >
> >| UPDATE Table SET Something =3D 'something' WHERE ID =3D 'id';
> >| IF NOT FOUND THEN
> >| INSERT INTO Table (ID, Something) VALUES ('id', 'something');
> >| END IF;
>=20
> ...was aber bei Nebenläufigkeit ohne explizites Locking zu Race Conditi=
ons=20
> führt. Was ist das Problem an Exceptions?

Sie fressen (laut Doku) Performance, denn intern werden sie mit Savepoints
implementiert.

Es stimmt allerdings, daß zwei solche Statements wie oben einander in die
Quere kommen können.

Allerdings lassen sich auch mit der "INSERT zuerst"-Methode Race Conditions
mit anderen Statements nicht ohne weiteres vermeiden:

CREATE TABLE test (id integer PRIMARY KEY, val text);
INSERT INTO test (id, val) VALUES (1, 'Wert');

Session A: Session B:

START TRANSACTION;
SAVEPOINT a;
INSERT INTO test (id, val) VALUES (1, 'Session a');
(ERROR: duplicate key value violates unique constraint "test_pkey")

DELETE FROM test WHERE id =3D 1;

ROLLBACK TO a;
UPDATE test SET val =3D 'Session a' WHERE id =3D 1;
(UPDATE 0)
COMMIT;

Wenn man die Transaktion in Session A serealisierbar macht
(START TRANSACTION ISOLATION LEVEL SERIALIZABLE in Session A),
wird der Erfolg auch nicht glücklich machen, dann bekommt die
Session A einen Error 40001.

Liebe Grüße,
Laurenz Albe

--=20
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

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

am 06.08.2008 10:09:24 von Markus Wanner

Hallo,

Albe Laurenz wrote:
> Wenn man die Transaktion in Session A serealisierbar macht
> (START TRANSACTION ISOLATION LEVEL SERIALIZABLE in Session A),
> wird der Erfolg auch nicht glücklich machen, dann bekommt die
> Session A einen Error 40001.

...was doch ein SERIALIZATION FAILURE, und deshalb absolut korrekt ist an=20
der Stelle. Bau auf Seite der Applikation einen retry-loop um die ganze=20
Veranstaltung und gut (und performant).

Im READ COMMITTED mode waere die Alternative noch, mit SELECT .. FOR=20
UPDATE zu testen, ob's solch ein Tuple schon gibt. Wenn ja, ein UPDATE=20
drauf, wenn nein den INSERT. Weniger performant als SERIALIZABLE=20
(pessimistic locking), aber Du sparst Dir damit evtl. den retry-loop in=20
der App (zumindest wenn Du auch noch darauf achtest, keine deadlocks zu=20
provozieren).

Gruesse

Markus Wanner

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

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

am 06.08.2008 10:24:24 von Bernd Helmle

--On Mittwoch, August 06, 2008 10:09:24 +0200 Markus Wanner=20
wrote:

> Im READ COMMITTED mode waere die Alternative noch, mit SELECT .. FOR
> UPDATE zu testen, ob's solch ein Tuple schon gibt. Wenn ja, ein UPDATE
> drauf, wenn nein den INSERT. Weniger performant als SERIALIZABLE
> (pessimistic locking), aber Du sparst Dir damit evtl. den retry-loop in
> der App (zumindest wenn Du auch noch darauf achtest, keine deadlocks zu
> provozieren).

In PostgreSQL sollte es eigentlich auf Datenbankebene keine Unterschiede zu=
=20
beiden geben, geschwindigkeitsmäßig. Ich weiß, das SAVEPOINTs Shared=
=20
Memory "fressen", aber "fressen" ist relativ. Wer sowas tausendfach in=20
einer Schleife macht, muß damit rechnen, irgendwann an die Grenzen der=20
Ressourcen zu stoßen. Dies innerhalb der Datenbank zu kapseln ist deutlic=
h=20
schöner als mit fehlerträchtigen Retry-Loops der Applikation zu spielen.

--=20
Thanks

Bernd

--=20
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

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

am 06.08.2008 10:26:43 von Bernd Helmle

--On Mittwoch, August 06, 2008 09:22:53 +0200 Albe Laurenz=20
wrote:

> Wenn man die Transaktion in Session A serealisierbar macht
> (START TRANSACTION ISOLATION LEVEL SERIALIZABLE in Session A),
> wird der Erfolg auch nicht glücklich machen, dann bekommt die
> Session A einen Error 40001.

Bei SERIALIZABLE muß die Anwendung darauf vorbereitet sein, die Aktion zu=
=20
wiederholen.

--=20
Thanks

Bernd

--=20
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

RE: [pgsql-de-allgemein] In Funktion prüfen ob Zei

am 06.08.2008 10:30:29 von Albe Laurenz

Markus Wanner schrieb:
> > Wenn man die Transaktion in Session A serealisierbar macht
> > (START TRANSACTION ISOLATION LEVEL SERIALIZABLE in Session A),
> > wird der Erfolg auch nicht glücklich machen, dann bekommt die
> > Session A einen Error 40001.
>=20
> ..was doch ein SERIALIZATION FAILURE, und deshalb absolut korrekt ist an=
=20
> der Stelle. Bau auf Seite der Applikation einen retry-loop um die ganze=
=20
> Veranstaltung und gut (und performant).

Ja, das ist völlig korrekt.
Ich wollte ja nur erwähnen, daß es noch ein paar andere Dinge zu
bedenken gibt.

Und mit einem nachträglichen Test könnte man auch die
"UPDATE first"-Methode krisensicher machen: Aktion wiederholen,
wenn das INSERT eine primary key violation ergibt.
Auch wenn das vielleicht weniger hübsch ist.

> Im READ COMMITTED mode waere die Alternative noch, mit SELECT .. FOR=20
> UPDATE zu testen, ob's solch ein Tuple schon gibt. Wenn ja, ein UPDATE=20
> drauf, wenn nein den INSERT. Weniger performant als SERIALIZABLE=20
> (pessimistic locking), aber Du sparst Dir damit evtl. den retry-loop in=
=20
> der App (zumindest wenn Du auch noch darauf achtest, keine deadlocks zu=
=20
> provozieren).

Session A: Session B:

START TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT 1 FROM test WHERE id =3D 1 FOR UPDATE;

?column?=20
----------
(0 rows)
START TRANSACTION ISOLATION LEVEL REA=
D COMMITTED;
SELECT 1 FROM test WHERE id =3D 1 FOR=
UPDATE;

?column?
----------
(0 rows)

INSERT INTO test (id, val) VALUES (1, 'Session a');
COMMIT;

INSERT INTO test (id, val) VALUES (1,=
'Session b');

ERROR: duplicate key value violates =
unique constraint "test_pkey"

Liebe Grüße,
Laurenz Albe

--=20
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

RE: [pgsql-de-allgemein] Re: [pgsql-de-allgeme

am 06.08.2008 11:07:52 von Albe Laurenz

Bernd Helmle schrieb:
> > Im READ COMMITTED mode waere die Alternative noch, mit SELECT .. FOR
> > UPDATE zu testen, ob's solch ein Tuple schon gibt. Wenn ja, ein UPDATE
> > drauf, wenn nein den INSERT. Weniger performant als SERIALIZABLE
> > (pessimistic locking), aber Du sparst Dir damit evtl. den retry-loop in
> > der App (zumindest wenn Du auch noch darauf achtest, keine deadlocks zu
> > provozieren).
>=20
> In PostgreSQL sollte es eigentlich auf Datenbankebene keine Unterschiede =
zu=20
> beiden geben, geschwindigkeitsmäßig. Ich weiß, das SAVEPOINTs Share=
d=20
> Memory "fressen", aber "fressen" ist relativ. Wer sowas tausendfach in=20
> einer Schleife macht, muß damit rechnen, irgendwann an die Grenzen der=
=20
> Ressourcen zu stoßen. Dies innerhalb der Datenbank zu kapseln ist deutl=
ich=20
> schöner als mit fehlerträchtigen Retry-Loops der Applikation zu spiel=
en.

Nanana, das ist jetzt aber frei fabuliert.

Die Doku sagt:
A block containing an EXCEPTION clause is significantly more expensive
to enter and exit than a block without one.
Therefore, don't use EXCEPTION without need.

Daß da ein Memory Leak in der Datenbank ist, kann ich dem nicht entnehmen=
...

Es ist mehr eine Performance-Angelegenheit.

Liebe Grüße,
Laurenz Albe

--=20
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

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

am 06.08.2008 11:10:15 von Markus Wanner

Hi,

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

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

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

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

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

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

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

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

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

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

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

Gruesse

Markus Wanner

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

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

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

am 06.08.2008 11:32:31 von Bernd Helmle

--On Mittwoch, August 06, 2008 11:07:52 +0200 Albe Laurenz=20
wrote:


>
> Nanana, das ist jetzt aber frei fabuliert.
>
> Die Doku sagt:
> A block containing an EXCEPTION clause is significantly more expensive
> to enter and exit than a block without one.
> Therefore, don't use EXCEPTION without need.
>
> Daß da ein Memory Leak in der Datenbank ist, kann ich dem nicht
> entnehmen ...

Das hat auch keiner behauptet ;)




--=20
Thanks

Bernd

--=20
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

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

am 06.08.2008 11:59:19 von Bernd Helmle

--On Mittwoch, August 06, 2008 11:10:15 +0200 Markus Wanner=20
wrote:

> 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.

Rowlocks in PostgreSQL werden über die XID realisiert und direkt im Tuple=
=20
Header gespeichert. Das alles ist sehr leichtfüßig, auch im SERIALIZABL=
E=20
Mode funktioniert das genauso, nur das er halt in dem Moment net sperrt=20
sondern einen Transaktionsfehler wirft, sollte XMAX bereits anderweitig=20
modifiziert worden sein. Die Unterschiede betreffen hier hauptsächlich di=
e=20
Art und Weise wie Snapshots erstellt werden, PostgreSQL ist hier sehr=20
intelligent implementiert, aber tatsächliche Performanceunterschiede zw.=
=20
READ COMMITTED und SERIALIZABLE ergeben sich wohl in der Art und Weise wie=
=20
die Anwendung mit beiden umzugehen hat. Rein von der Datenbankengine=20
gesehen müsste SERIALIZABLE sogar schneller sein, da es weniger Snapshots=
=20
erzeugen muß!

Im übrigen bin ich absolut deiner Meinung, und Exceptions sind nichts=20
schlimmes.


--=20
Thanks

Bernd

--=20
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

Re: [pgsql-de-allgemein] Re: [pgsql-de-allgemein] Re: [pgsql-de-allgemein] RE: [pgsql-de-allgemein]

am 06.08.2008 12:50:16 von Markus Wanner

Hi,

Bernd Helmle wrote:
> Rowlocks in PostgreSQL werden über die XID realisiert und direkt im=20
> Tuple Header gespeichert. Das alles ist sehr leichtfüßig, auch im=20
> SERIALIZABLE Mode funktioniert das genauso, nur das er halt in dem=20
> Moment net sperrt sondern einen Transaktionsfehler wirft, sollte XMAX=20
> bereits anderweitig modifiziert worden sein.

Genau.

> Die Unterschiede betreffen=20
> hier hauptsächlich die Art und Weise wie Snapshots erstellt werden,=20
> PostgreSQL ist hier sehr intelligent implementiert, aber tatsächliche=
=20
> Performanceunterschiede zw. READ COMMITTED und SERIALIZABLE ergeben sic=
h=20
> wohl in der Art und Weise wie die Anwendung mit beiden umzugehen hat.=20

Richtig.

Die READ COMMITTED Anwendung sollte(!) aber haeufiger SELECT FOR UPDATE=20
nutzen, um korrekt zu locken. Dies modifiziert ebenfalls den tuple=20
header und setzt xmax schon mal auf die aktuelle xid, um das Tuple zu=20
sperren. Dies wird als pessimistic locking bezeichnet, weil dies die=20
Erwartung eines Konflikts impliziert.

Wenn aber kein Konflikt vorliegt dann stellt das ein unnoetiger Schritt=20
dar, den Du Dir bei SERIALIZABLE meist sparen kannst. Man beachte, dass=20
dieser Schritt ggf. sogar zu Diskzugriffen fuehrt, die in dem Fall=20
eigentlich ebenso unnoetig sind.

> Rein von der Datenbankengine gesehen müsste SERIALIZABLE sogar schnel=
ler=20
> sein, da es weniger Snapshots erzeugen muß!

Verglichen mit READ COMMITTED ist SERIALIZABLE schneller, wenn wenige=20
Konflikte zu erwarten sind - weniger wegen der Snapshots, sondern viel=20
eher durch optimistisches Locking. Je haeufiger Konflikte auftreten,=20
desto eher wird READ COMMITTED auf- oder sogar ueberholen.

Gruesse

Markus Wanner


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