sql >> Databasteknik >  >> RDS >> PostgreSQL

uppenbar transaktionsisoleringsöverträdelse i postgresql

Ja och nej – som vanligt beror det på. Dokumentationen säger strikt att:

Med andra ord, helt enkelt SELECT skiljer sig från SELECT FOR UPDATE/DELETE/UPDATE.

Du kan skapa enkla testfall för att observera det beteendet:

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

Logga in nu i en annan 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 det sista kommandot SELECT ... FOR UPDATE session 1 "hänger" och väntar på något ......

Tillbaka i session 1

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

Och nu när du går tillbaka till session 2 kommer du att se detta:

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 vill säga - enkel SELECT ser fortfarande inga ändringar, medan SELECT ... FOR UPDATE ser att rader har tagits bort. Men den ser inte nya rader infogade av session 1

Faktum är att en sekvens du ser är:

  • process A startar sin transaktion
  • process A tar bort allt från tabell T
  • process B startar sin transaktion
  • process B försöker välja för uppdatering på en rad i tabell T
  • process B "hänger sig" och väntar tills session A gör en commit eller rollback
  • process A fyller på tabell T från inkommande data
  • process A genomför sin transaktion
  • process B visas tom (0 rader - efter session A commit) och anropar återställning



  1. Solr-sökning med Mysql Database, vilket som helst verktyg för dataimport

  2. Köra ett MariaDB Galera Cluster utan Orchestration Tools - DB Container Management:Del två

  3. SQL Server:Behöver jag använda GO-satser mellan batcher?

  4. MySQL-replikering för hög tillgänglighet