sql >> Database >  >> RDS >> PostgreSQL

duidelijke schending van transactie-isolatie in postgresql

Ja en Nee - zoals gewoonlijk hangt het ervan af. De documentatie zegt strikt dat:

Met andere woorden, gewoon SELECT verschilt van SELECT FOR UPDATE/DELETE/UPDATE.

U kunt een eenvoudige testcase maken om dat gedrag te observeren:

Sessie 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 in op een andere Sessie 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;

Na het laatste commando SELECT ... FOR UPDATE sessie 1 "hangt" en wacht op iets ......

Terug in sessie 1

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

En als je nu teruggaat naar sessie 2, zie je dit:

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)

Dat wil zeggen - eenvoudig SELECT ziet nog steeds geen wijzigingen, terwijl SELECT ... FOR UPDATE ziet wel dat rijen zijn verwijderd. Maar er worden geen nieuwe rijen ingevoegd door sessie 1

In feite is een reeks die u ziet:

  • proces A begint zijn transactie
  • proces A verwijdert alles uit tabel T
  • proces B start zijn transactie
  • proces B probeert een selectie voor update op één rij in tabel T
  • proces B "hangt" en wacht tot sessie A een commit of rollback doet
  • proces A vult tabel T opnieuw met inkomende gegevens
  • proces A voert zijn transactie uit
  • proces B wordt leeg weergegeven (0 rijen - na vastlegging van sessie A) en roept rollback op



  1. Oracle:Combineer meerdere resultaten in een subquery tot één door komma's gescheiden waarde

  2. ON DELETE CASCADE werkt niet in MySQL

  3. Kan ik de retourwaarde van INSERT...RETURNING gebruiken in een andere INSERT?

  4. async en wacht op MySQL-oproep in node js