Вы правы: при стандартном уровне изоляции , read committed
вам не нужно заключать операторы выбора в транзакции. Операторы выбора будут защищены от грязного чтения, независимо от того, заключите вы их в транзакцию или нет.
connection 1: connection 2:
begin transaction
update user set name = 'Bill' where id = 1
select name from users where id = 1
rollback transaction
Оператор выбора не будет читать откатное обновление: не имеет значения, что они не включены в транзакцию.
Если вам нужно повторяющихся чтений , то перенос по умолчанию в транзакции по умолчанию не помогает:
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
Здесь не помогут операторы begin
и commit
: второй select
может прочитать старое имя или может прочитать новое имя.
Однако, если вы используете более высокий уровень изоляции, например serializable
или repeatable read
, группа будет защищена от неповторяющихся чтений:
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
В этом сценарии update
будет блокироваться до завершения первой транзакции.
Более высокие уровни изоляции используются редко, поскольку они уменьшают количество людей, которые могут работать в базе данных одновременно. На самом высоком уровне, serializable
, отчетный запрос останавливает любую операцию обновления.