PostgreSQL & Transakion

Hallo

Ich hab ein großes Verständnisproblem mit Transaktionen:
Ich mache folgenden Ablauf:

SESSION 1:
BEGIN;

SESSION 2:
BEGIN;
UPDATE foo SET zahl = zahl + 20;

SESSION 1:
UPDATE foo SET zahl = zahl + 20;

SESSION 2:
COMMIT;

SESSION 1:
COMMIT;

Laut meinem Buch sollte jetzt eine Inkonsistenz bestehen - was meiner Meinung nach so viel bedeutet dass bei einem Startwert von 100 beide auf 120 setzen - und nicht wie gewünscht 140.
Das soll der Fall sein wegen READ COMMITTED

Bei mir kommt es aber ganz anders: Das Update in SESSION 1 blockiert so lange bis ich in SESSION 2 commite :-S

Warum das? Wäre das nicht das Verhalten von SERIALIZABLE?

Danke im Voraus
lg

Welches Buch ist das?


Bei mir kommt es aber ganz anders: Das Update in SESSION 1 blockiert so lange bis ich in SESSION 2 commite :-S

Warum das? Wäre das nicht das Verhalten von SERIALIZABLE?

Danke im Voraus
lg

SERIALIZABLE würde auch blockieren, allerdings würde dann die TX, die zuerst commited, gewinnen und die andere einen Fehler bekommen: “ERROR: could not serialize access due to concurrent update”.

Andreas

Danke für die rasche Antwort

“PostgreSQL - professionell und praxisnah . (Programmer’s Choice)” von Jens Hartwig (Autor)

Jo - so steht das auch drinnen. Nur das erste Bsp kann ich net nachvollziehen :confused:

Komisch. Ich hab das Buch nicht. Entweder Fehler dort, Buch zu alt oder ein Layer 8 Problem.

Andreas

Layer 8 ist möglich :wink:

Das Buch ist halt für 7.2. War das dort anders? Kann ich mir fast nicht denken - wie auch immer - vl. meinte der Autor das anders.

Danke
lg

Eine Frage hätte ich noch:
Ich hab folgenden Table:
bookid => integer
bookname => text

Nun habe ich einen Datensatz drin: bookid=1 bookname=‘buch 1’
Ohne jetzt serial zu verwenden (bewusst):
BEGIN;
LOCK TABLE books;
INSERT INTO books VALUE((SELECT MAX(bookdid) + 1), ‘buch2’);
COMMIT;

Das Problem ist ja, dass SELECT MAX(…) in mehreren Sessions “1” als ID zurückliefern kann

Nun meine Fragen:

  • Angenommen das LOCK TABLE ist nicht da: habe ich die Garantie dass dieses Statement atomar ausgeführt wird?
  • Brauche ich hier den vollen “ACCESS EXCLUSIVE MODE”?

lg

Eine Frage habe ich noch:

In meinem Buch ist ein Beispiel wo Rechnungen etc fürn Versand erstellt werden. Der Autor benutzt “LOCK TABLE … IN SHARE MODE” mit dem Kommentar “Tabelle … gegen Änderungen sperren”.

Wenn nun aber 2 Tabellen im SHARE MODE locken ohne SELECT oder INSERT zu machen habe ich ja einen Deadlock. Sollte man da net einen SHARE ROW EXCLSUIVE MODE machen?

Danke im Voraus
lg

Schau Dir mal SELECT … FOR UPDATE an, PostgreSQL: Documentation: Manuals: PostgreSQL 8.2: SELECT , damit läßt sich so ziemlich alles erschlagen IMHO.

Andreas

Sorry für die späte Antwort

Hmm. Damit kann ich aber mein Problem aus Post#6 nicht lösen oder?
SELECT FOR UPDATE verhindert ja nur ein ändern - aber das SELECT geht ja noch immer und beide würden den gleichen Datensatz bekommen. Besser zu sehen hier (geschrieben in plpgsql):

DECLARE
myMaxID INT4;
BEGIN
SELECT MAX(bookid) + 1 INTO myMaxID FROM bookatble;

END;

Nun wird die Funktion angenommen 2 Mal parallel aufgerufen - nun hat myMaxID 2 Mal die Zahl “4” - ich hätte somit 2 Bücher mit der ID 4.

Das geht nur mit einem expliziten Lock oder?

lg