De enige draagbare manier om consistentie tussen kamers en tags te bereiken en ervoor te zorgen dat kamers nooit worden geretourneerd nadat ze zijn verwijderd, is ze te vergrendelen met SELECT FOR UPDATE .
In sommige systemen is vergrendeling echter een neveneffect van gelijktijdigheidscontrole en bereikt u dezelfde resultaten zonder FOR UPDATE op te geven. expliciet.
Om dit probleem op te lossen, moet Thread 1 SELECT id FROM rooms FOR UPDATE , waardoor wordt voorkomen dat Thread 2 wordt verwijderd uit rooms totdat draad 1 klaar is. Klopt dat?
Dit hangt af van het gelijktijdigheidsbeheer dat uw databasesysteem gebruikt.
-
MyISAMinMySQL(en verschillende andere oude systemen) vergrendelt de hele tabel voor de duur van een zoekopdracht. -
In
SQL Server,SELECTquery's plaatsen gedeelde vergrendelingen op de records / pagina's / tabellen die ze hebben onderzocht, terwijlDMLquery's plaatsen updatevergrendelingen (die later worden gepromoveerd tot exclusieve of gedegradeerd tot gedeelde vergrendelingen). Exclusieve sloten zijn niet compatibel met gedeelde sloten, dus ofwelSELECTofDELETEquery wordt vergrendeld totdat een andere sessie wordt vastgelegd. -
In databases die
MVCC. gebruiken (zoalsOracle,PostgreSQL,MySQLmetInnoDB), eenDMLquery maakt een kopie van het record (op de een of andere manier) en over het algemeen blokkeren lezers geen schrijvers en vice versa. Voor deze databases, eenSELECT FOR UPDATEzou handig zijn:het zou ofwelSELECT. vergrendelen of deDELETEquery totdat een andere sessie zich commit, net alsSQL Serverdoet.
Wanneer moet men REPEATABLE_READ gebruiken? transactie-isolatie versus READ_COMMITTED met SELECT ... FOR UPDATE ?
Over het algemeen REPEATABLE READ verbiedt geen fantoomrijen (rijen die zijn verschenen of verdwenen in een andere transactie, in plaats van te worden gewijzigd)
-
In
Oracleen eerderPostgreSQLversies,REPEATABLE READis eigenlijk een synoniem voorSERIALIZABLE. Kort gezegd betekent dit dat de transactie geen wijzigingen meer ziet die zijn aangebracht nadat deze is gestart. Dus in deze opstelling is de laatsteThread 1query zal de kamer retourneren alsof deze nooit is verwijderd (wat al dan niet is wat je wilde). Als je de kamers niet wilt tonen nadat ze zijn verwijderd, moet je de rijen vergrendelen metSELECT FOR UPDATE -
In
InnoDB,REPEATABLE READenSERIALIZABLEzijn verschillende dingen:lezers inSERIALIZABLEmode zet next-key locks op de records die ze evalueren, waardoor de gelijktijdigeDMLeffectief wordt voorkomen op hen. Je hebt dus geenSELECT FOR UPDATEnodig in serialiseerbare modus, maar heb ze wel nodig inREPEATABLE READofREAD COMMITED.
Merk op dat de standaard over isolatiemodi voorschrijft dat u bepaalde eigenaardigheden niet in uw zoekopdrachten ziet, maar niet definieert hoe (met vergrendeling of met MVCC of anderszins).
Als ik zeg "je hebt SELECT FOR UPDATE niet nodig" " Ik had eigenlijk moeten toevoegen "vanwege bijwerkingen van bepaalde database-engine-implementaties".