Hai ragione:al livello di isolamento
standard , read committed
, non è necessario racchiudere estratti selezionati nelle transazioni. Le istruzioni selezionate saranno protette da letture sporche indipendentemente dal fatto che le avvolga in una transazione o meno.
connection 1: connection 2:
begin transaction
update user set name = 'Bill' where id = 1
select name from users where id = 1
rollback transaction
L'istruzione select non leggerà l'aggiornamento ripristinato:non importa che non siano racchiusi in una transazione.
Se hai bisogno di letture ripetibili , quindi il wrapping delle selezioni in una transazione predefinita non aiuta:
connection 1: connection 2:
begin transaction
select name from users where id = 1
update user set name = 'Bill' where id = 1
select name from users where id = 1
commit transaction
Il begin
e commit
le istruzioni non aiutano qui:la seconda select
può leggi il vecchio nome, oppure potrebbe leggi il nuovo nome.
Tuttavia, se esegui un livello di isolamento più elevato, come serializable
o repeatable read
, il gruppo sarà protetto da letture non ripetibili:
connection 1: connection 2:
set transaction isolation level
repeatable read
begin transaction
select name from users where id = 1
update user set name = 'Bill' where id = 1
select name from users where id = 1 |
commit transaction |
|--> executed here
In questo scenario, l'update
si bloccherà fino al completamento della prima transazione.
Raramente vengono utilizzati livelli di isolamento più elevati perché riducono il numero di persone che possono lavorare contemporaneamente nel database. Al livello più alto, serializable
, una query di rapporto interrompe qualsiasi attività di aggiornamento.