sql >> Database teknologi >  >> RDS >> PostgreSQL

tilsyneladende brud på transaktionsisolering i postgresql

Ja og nej – det afhænger som sædvanligt. Dokumentationen siger strengt taget at:

Med andre ord, blot SELECT adskiller sig fra SELECT FOR UPDATE/DELETE/UPDATE.

Du kan oprette en simpel testcase for at observere denne adfærd:

Session 1

test=> START TRANSACTION;
START TRANSACTION
test=> SELECT * FROM test;
 x
----
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
(10 rows)


test=> DELETE FROM test;
DELETE 10
test=>

Log nu ind i en anden session 2:

test=> START TRANSACTION;
START TRANSACTION
test=> SELECT * FROM test;
 x
----
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
(10 rows)


test=> SELECT * FROM test WHERE x = 5 FOR UPDATE;

Efter den sidste kommando SELECT ... FOR UPDATE session 1 "hænger" og venter på noget ......

Tilbage i session 1

test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT

Når du nu går tilbage til session 2, vil du se dette:

test=> SELECT * FROM test WHERE x = 5 FOR UPDATE;
 x
---
(0 rows)


test=> select * from test;
 x
----
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
(10 rows)

Det vil sige - simpel SELECT kan stadig ikke se nogen ændringer, mens SELECT ... FOR UPDATE ser, at rækker er blevet slettet. Men den ser ikke nye rækker indsat af session 1

Faktisk er en sekvens du ser:

  • proces A starter sin transaktion
  • proces A sletter alt fra tabel T
  • proces B starter sin transaktion
  • proces B forsøger at vælge til opdatering på én række i tabel T
  • proces B "hænger" og venter, indtil session A foretager en commit eller rollback
  • proces A genudfylder tabel T fra indgående data
  • proces A forpligter sin transaktion
  • proces B vises tom (0 rækker - efter session A commit) og kalder rollback



  1. Jeg vil gerne finde alle lederes navne og deres alle lederes navn i oracle SQL

  2. mySQL fejl:#1248 - Hver afledt tabel skal have sit eget alias

  3. MySQL INSERT ... PÅ DUBLIKAT NØGLOPDATERING på Java:Sådan adskiller du indsatte/opdaterede/NoChange-tilstande

  4. Oracle sql-afledt tabel - valgfri aliasing