Вопрос 1 Тут по ссылке
src-code.net/koncepciya-blokirovok-v-sql-server приведена такая таблица:
Таблица 51.4. Уровни изоляции и продолжительность блокировки
Уровень изоляции - Продолжительность общей блокировки
Read Uncommited - Отсутствует
Read Commited - Удерживается во время чтения данных
Объясните, в чем будет разница между "Отсутствует" и "Удерживается во время чтения данных".
Вопрос 2 https://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%BE%D...
Почему в описании уровней изоляции транзакций описываются только проблемы повторного чтения ОДНИХ И ТЕХ ЖЕ данных (неповторяющееся чтение, фантомное чтение), но при этом никогда не пишется про артефакты, которые могут возникать при чтении РАЗНЫХ (но взаимосвязанных) данных при уровнях изоляции ниже RepeatableRead? Вот пример (можно придумать пример с разными таблицами, но я тут приведу пример с одной таблицей, но разными строками, которые взаимозависимы):
Есть таблица Юзеров с суммами их счетов, т.е. в таблице 2 колонки - UserName и AmountSum. Юзер1 имеет сумму 10 руб, Юзер2 тоже имеет сумму 10 руб. Юзер1 переводит Юзеру2 5 руб. Система открывает транзакцию уровня ReadCommitted, внутри транзакции выполняются такие скрипты:
/*#time1*/Update Users
Set AmountSum = AmountSum + 5
Where UserName = 'Юзер2';
/*#time4*/Update Users
Set AmountSum = AmountSum - 5
Where UserName = 'Юзер1';
/*#time5*/
В это же время админ системы решил посмотреть, сколько денег на счетах у Юзера1 и Юзера2. Он выбрал этих юзеров в интерфейсе и нажал кнопку "показать". Система запускает транзакцию уровня ReadCommitted, внутри транзакции написан цикл, который для каждого выбранного юзера выполняет отдельный select-запрос. В итоге внутри транзакции выполнятся 2 таких селекта:
/*#time2*/Select *
From Users
Where UserName = 'Юзер1';
/*#time3*/Select *
From Users
Where UserName = 'Юзер2';
/*#time1*/ -...- /*#time4*/ - это обозначение порядка выполнения запросов. Получается, что:
1) на #time1 первый апдейт добавляет к счету Юзера2 5 руб, делая сумму его счета = 15руб, при этом апдейт ставит эксклюзивную блокировку до конца транзакции на строку Юзера2.
2) на #time2 первый селект читает сумму счета Юзера1, она пока еще равна 10 руб, shared-блокировка ставится только на время селекта, т.е. во время #time3 shared-блокировки Юзера1 уже нет.
3) на на #time3 второй селект читает сумму счета Юзера2, но на Юзере2 стоит эксклюзивная блокировка, поэтому селект не может прочитать сумму Юзера2 и стопорится.
4) на #time4 второй апдейт вычитает из счета Юзера1 5 руб, делая сумму его счета = 5руб, при этом апдейт ставит эксклюзивную блокировку до конца транзакции на строку Юзера1.
5) на /*#time5*/ транзакция обновления данных завершается, и с Юзеров 1 и 2 снимаются все блокировки.
6) наконец после разблокировки всех строк транзакция считывания может прочитать сумму счета Юзера2, которую не смогла прочитать на #time3 из-за блокировки, сумма счета Юзера2 равна 15 руб.
В итоге в этой ситуации получается, что Админ увидит такие суммы счетов: Юзер1 - 10руб, Юзер2 - 15 руб. Данные оказались тупо несогласованы. Самое странное, что я не видел такого примера в статьях про уровни изоляции в SQL, везде только про "неповторяемое чтение" (т.е. несогласованные данные) при чтении одних и тех же данных. Хотя я с трудом представляю, зачем на практике нужно 2 раза считывать одни и те же данные. Зато при чтении разных, но зависимых данных, которое реально в 99% случаев в транзакциях, получается аналог "неповторяемого чтения" (такие же несогласованные данные), но про такой кейс нигде не написано.
Кто-нибудь может это объяснить?