sql >> Databáze >  >> RDS >> PostgreSQL

zjevné porušení izolace transakcí v postgresql

Ano a Ne - jako obvykle, záleží. Dokumentace přesně říká, že:

Jinými slovy, jednoduše SELECT se liší od SELECT FOR UPDATE/DELETE/UPDATE.

Můžete vytvořit jednoduchý testovací případ a pozorovat toto chování:

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

Nyní se přihlaste v další relaci 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;

Po posledním příkazu SELECT ... FOR UPDATE relace 1 "visí" a na něco čeká ......

Zpět v relaci 1

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

A teď, když se vrátíte k relaci 2, uvidíte toto:

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)

Tedy - jednoduché SELECT stále nevidí žádné změny, zatímco SELECT ... FOR UPDATE vidí, že řádky byly smazány. Nevidí však nové řádky vložené relací 1

Ve skutečnosti sekvence, kterou vidíte, je:

  • proces A zahájí svou transakci
  • proces A odstraní vše z tabulky T
  • proces B zahájí svou transakci
  • proces B se pokusí vybrat aktualizaci jednoho řádku v tabulce T
  • proces B se „zasekne“ a čeká, dokud relace A neprovede potvrzení nebo vrácení zpět
  • proces A znovu naplní tabulku T z příchozích dat
  • proces A potvrdí svou transakci
  • proces B je prázdný (0 řádků – po potvrzení relace A) a volá rollback



  1. Dotaz na prvky pole uvnitř typu JSON

  2. Nebyla vybrána žádná sada záloh k obnovení SQL Server 2012

  3. Aktualizace zobrazení Join, aniž by došlo k chybě bez zachování klíče

  4. Jak vložit data objednávky z vícerozměrného pole