Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите разобраться с уровнями изоляции транзакций.  [new]
questioner
Member

Откуда:
Сообщений: 1906
Прочитал на википедии статью:
https://ru.wikipedia.org/wiki/Уровень_изолированности_транзакций
и тут
http://stackoverflow.com/questions/11043712/what-is-difference-between-non-repeatable-read-and-phantom-read
Всё построено по такому принципу, что Read uncommitted запрещает только X, Read committed X+Y, Repeatabe read X+Y+Z, Serializable X+Y+Z+G

Собственно как я понял:

1. Serializable
Если какая-то транзакция началась, то все данные(все таблицы) с которыми она работает, заблокированы и никто(кроме текущей транзакции) не может их менять пока транзакция не закончилась. Сторонняя транзакция НЕ может добавлять и удалять строки (но не менять).
2 последовательных одинаковых запроса обязательно вернут один и тот же результат.

2. Repeatabe read
2 последовательных одинаковых запроса могут вернуть разное количество строк, но те строки, которые есть и в 1 ответе и во втором обязательно остались неизменными.

То есть так....

select * from table1
                                update table1....    // изменить строку 3
                                delete from table1....//удалить строку 2
                                insert into table1...  //добавить строку 6
                                commit
select * from table1                               


слева транзакция A, справа транзакция B.

Так вот второй select транзакции A не увидит изменения строки 3.

Только я не совсем понимаю как это реализовано.
Без коммита транзакция А вообще ничего нового не увидит

3.Read committed
В вышеприведенном примере Транзакция А увидит изменения транзакции B (строки 3)
Без коммита транзакция А вообще ничего нового не увидит
4.Read uncommitted
Теперь одна транзакция может увидеть некоторые изменения другой даже если эта другая их не закоммитила.
а некоторые это какие?

Картинка с другого сайта.

на вики приведен такой вот пример. Как я понял, транзакция 2 не увидит update, сделанный транзакцией 1

только я чо то не понимаю вообще как это может происходить. транзакция 2 что ли умеет вперед смотреть или как?


Ну и если бы изоляции вообще не было , то вообще всё было бы видно между транзакциями(никаких тайн)

Вот как я сейчас это вижу всё. Поясните пожалуйста ситуация.
Чувствую, что я плаваю в этой теме.
5 окт 14, 15:34    [16663103]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
https://www.sql.ru/forum/165996/posovetuyte-chtivo-o-blokirovkah
5 окт 14, 16:37    [16663168]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
Exproment
Member

Откуда:
Сообщений: 416
questioner
Всё построено по такому принципу, что Read uncommitted запрещает только X, Read committed X+Y, Repeatabe read X+Y+Z, Serializable X+Y+Z+G

не правильно поняли. Уровни изоляции отличаются исключительно блокировками, которые они накладывают. А не тем, что они запрещают.
questioner
1. Serializable
Если какая-то транзакция началась, то все данные(все таблицы) с которыми она работает,

не правильно поняли
questioner
...

Остальное даже понять невозможно. Уберите слова "увидит", т.к. нет никаких уровней видимости в уровнях изоляции. Читайте литературу, смотрите семинары.
5 окт 14, 16:45    [16663175]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
questioner
Member

Откуда:
Сообщений: 1906
Exproment,

ну я вообще хотел, чтобы меня поправили, а не просто указали где я не прав.

по поводу

автор
не правильно поняли. Уровни изоляции отличаются исключительно блокировками, которые они накладывают. А не тем, что они запрещают.


Картинка с другого сайта.

тут разве что-то другое имели ввиду?
5 окт 14, 17:40    [16663210]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
questioner
Member

Откуда:
Сообщений: 1906
Гавриленко Сергей Алексеевич
https://www.sql.ru/forum/165996/posovetuyte-chtivo-o-blokirovkah


Мне не нужно таких прям деталей. Я думаю будет достаточно понять на верхнем уровне абстракции без привязки даже к конкретной субд.
5 окт 14, 17:42    [16663214]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
Exproment
Уровни изоляции отличаются исключительно блокировками, которые они накладывают.
На Repeatable Read и Serializable могут быть наложены идентичные блокировки. Чем же они тогда отличаются?
Не путайте ТС'а еще больше.
5 окт 14, 17:56    [16663250]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
questioner
Member

Откуда:
Сообщений: 1906
Давайте хотя бы на примере read uncommitted поговорим.
Тот, пример, что я скопировал с Вики:

Как защищаются от этой "проблемы" на более защищенных уровнях?
транзакция 2 будет просто ждать пока транзакция 1 не завершится?

Если так, то транзакция 1 должна уведомить субд о том, что мол заблокируй ка ты эту таблицу/строки. Вопрос как транзакция понимает, что она будет откачена. Или эта блокировка происходит всегда когда в тексте транзакции есть rollout?
5 окт 14, 18:31    [16663325]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
questioner
Давайте хотя бы на примере read uncommitted поговорим.
Тот, пример, что я скопировал с Вики:

Как защищаются от этой "проблемы" на более защищенных уровнях?
транзакция 2 будет просто ждать пока транзакция 1 не завершится?

Если так, то транзакция 1 должна уведомить субд о том, что мол заблокируй ка ты эту таблицу/строки. Вопрос как транзакция понимает, что она будет откачена. Или эта блокировка происходит всегда когда в тексте транзакции есть rollout?
В MSSQL все разруливается блокировками, их типами, гранулярностью и длительностью. Но вам это не интересно.
5 окт 14, 19:30    [16663460]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
gandjustas
Member

Откуда:
Сообщений: 857
Блог
questioner
Чувствую, что я плаваю в этой теме.

Есть децл.

Надо начать с того, что такое Изолированность транзакций (I в ACID). Изолированность означает что каждая транзакция выполняется так, как будто других транзакций не существует, а несколько параллельных транзакций выполняется так, как-будто они выполнялись последовательно. Заранее порядок не оговаривается, важно чтобы он был.

Какие могут быть проблемы при параллельной работе транзакций:
1) Потерянное обновление - когда две транзакции читают и обновляют одну и ту же ячейку (поле в строке) параллельно. Например на счет начисляют проценты параллельно несколько транзакций. Одна пытается увеличить на 0,3%, вторая на 0,2%. Так как обе прочитали начальное значение одновременно, то в результате счет будет увеличен один раз.

2) Грязное чтение - когда одна транзакция меняет данные, а другая их читает, после чего первая откатывается. Например идут две транзакции, пытающиеся снять деньги со счета. На счету 100 рублей, первая пытается снять 30, но откатывается. Вторая пытается снять еще 50, но успевает прочитать значение счета после измененияи до коммита, то есть 70 рублей. В итоге на счету будет 20 рублей.

3) Неповторяемое чтение - когда одна транзакция читает данные несколько раз, а вторая успевает их обновить.
Две транзакции работают параллельно, она начисляет процент, вторая снимает сумму со скидкой в зависимости от состояния счета. Начисление процента происходит по нетривиальной формуле. Первая транзакция читает счет и уходит на вычисления процента, вторая быстро успевает обновить счет, пока первая думает, первая транзакция начисляет процент по неактуальной сумме.

4) Фантомное чтение - когда одна транзакция читает строки по предикату, а вторая меняет их, так что повторное чтение в первой транзакции возвращает разный набор строк. Все предыдущие проблемы проявлялись на одной строке, фантомное чтение проявлятся когда строк более чем одна. Классический пример - баланс. Одна транзакция считает сумму средств на счетах, а вторая переводит с одного счета на другой (обновляет две записи по очереди). Первая транзакция может посчитать баланс между двумя обновлениями второй транзакции, получив неверный баланс.


Эти 4 проблемы приводят к тому, что результат нескольких параллельных транзакций не соответствует какому-либо порядку их последовательного выполнения.

Есть теорема о сериализуемости транзакций, которая говорит, что сериализуемость можно сделать используя двухфазный протокол блокировки. Когда в первой фазе навешиваются блокировки на строки, а во второй фазе снимаются. Причем для любого набора транзакций можно добиться их сериализумости если вторая фаза (снятие блокировок) происходит после коммита.

Увы в реальности такая строгая сериализуемость убивает параллельность (и скорость работы) и повышает количество дедлоков, поэтому придумано два способа оптимизации:
1) Разные типы и гранулярности блокировок
2) Разные уровни изоляции (по сути разные правила навешивания блокировок)

Само по себе название "уровень изоляции" плохо описывает происходящее. Ибо честная изоляция с точки зрения ACID, возможна только на уровне Serializable. Тогда сама база данных гарантирует, что любое количество транзакций, выполняющихся параллельно, имеют результат как при некотором последовательном выполнении. Все остальные уровни изоляции, кроме serializable, перекладывают на разработчика ответственность за сохранение изолированности транзакций.

Сам уровни изоляции привязаны как раз к потенциальным проблемам, которые они допускают:
1) Serializable - обеспечивает честную изолированность транзакций.
2) Repeatable Read - допускает фантомные чтения, сам разработчик должен следить чтобы целостность данных не была нарушена из-за фантомных чтений.
3) Read Commited - допускает фантомные чтения и неповторяемые чтения. Соответственно сам разработчик должен следить за отсутствием проблем из-за неповторяемых чтений.
4) Read Uncommited - допускает фантомные чтения, неповторяемые чтения и даже грязные чтения.

Кроме обеспечения изоляции с помощью блокировок есть и другой путь, называется Multi-Version Concurrency Control. С недавнего времени полностью поддерживается в SQL Server и называется SNAPSHOT. Суть в том, что вместо блокировок, снижающих параллельность, каждой транзакции отдается свой слепок данных, при попытке записи каждая транзакция создает копию данных, обновляет её, а при коммите копия становится "текущей" версией. Старые версии, на которые уже не ссылается ни одна транзакция, удаляются. Такой подход требует больше ресурсов, но при этом дает большую параллельность. Кроме того при записи сверяются версии, если другая транзакция успела поменять версию, то транзакция откатывается.

Самая главная фишка, что при таком подходе нету ни фантомных чтений, ни неповторяемых или грязных чтений, но НЕ обеспечивается честная сериализуемость, так как можно сделать две параллельные транзакции, результат которых не соответствует ни одному порядку их последовательного выполнения.

Можно также применять MVCC на уровне отдельных строк, запись в строку ведет к созданию версии строки, а не навешиванию блокировки. Чтение всегда читает "текущую" версию. А при коммите новая версия пишется вместо старой. Это позволяет добиться гарантий Read Commited без блокировок на чтение, но с вероятностью отката записи. В SQL Server это называется Read Commited Snapshot Isolation и не является отдельным уровнем изоляции, а флагом на уровне БД, который переключает режим работы, так как нельзя совместить блокировки и MVCC и сохранить гарантии.
5 окт 14, 21:02    [16663623]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
questioner
Member

Откуда:
Сообщений: 1906
gandjustas,
в 3 и 4 пункте я понимаю, что чтобы избежать Неповторяемое чтение нужно просто блочить те строки, с которыми работает транзакция, чтобы избежать Фантомное чтение нужно блочить все таблицы, с которыми работает транзакция.

Вот тут не понимаю в чем разница?
gandjustas
1) Потерянное обновление - когда две транзакции читают и обновляют одну и ту же ячейку (поле в строке) параллельно. Например на счет начисляют проценты параллельно несколько транзакций. Одна пытается увеличить на 0,3%, вторая на 0,2%. Так как обе прочитали начальное значение одновременно, то в результате счет будет увеличен один раз.

2) Грязное чтение - когда одна транзакция меняет данные, а другая их читает, после чего первая откатывается. Например идут две транзакции, пытающиеся снять деньги со счета. На счету 100 рублей, первая пытается снять 30, но откатывается. Вторая пытается снять еще 50, но успевает прочитать значение счета после измененияи до коммита, то есть 70 рублей. В итоге на счету будет 20 рублей.


Почему выделяют такие 2 уровня возможных ошибок?
6 окт 14, 13:14    [16665697]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8828
Это же разные процессы. В первом - конкурентное обновление, во втором - недостоверное чтение.
6 окт 14, 13:28    [16665764]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
questioner
Member

Откуда:
Сообщений: 1906
Владислав Колосов
Это же разные процессы. В первом - конкурентное обновление, во втором - недостоверное чтение.


воспользуемся вики:

конкурентное обновление:

Картинка с другого сайта.

недостоверное чтение:

Картинка с другого сайта.

Какую такую блокировку можно придумать для того, чтобы конкурентное чтение пофиксить, а недостоверное чтение разрешить?
6 окт 14, 17:28    [16667488]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
Glory
Member

Откуда:
Сообщений: 104751
questioner
а недостоверное чтение разрешить?

Грязные данные может попробовать прочитать любое соединение, незавсимо от того, какие TIL заданые в других соединениях.
Вот только запросто может огрести ошибку при чтении этих данных.
6 окт 14, 17:30    [16667503]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с уровнями изоляции транзакций.  [new]
gandjustas
Member

Откуда:
Сообщений: 857
Блог
questioner
gandjustas,
в 3 и 4 пункте я понимаю, что чтобы избежать Неповторяемое чтение нужно просто блочить те строки, с которыми работает транзакция, чтобы избежать Фантомное чтение нужно блочить все таблицы, с которыми работает транзакция.

Вот тут не понимаю в чем разница?
gandjustas
1) Потерянное обновление - когда две транзакции читают и обновляют одну и ту же ячейку (поле в строке) параллельно. Например на счет начисляют проценты параллельно несколько транзакций. Одна пытается увеличить на 0,3%, вторая на 0,2%. Так как обе прочитали начальное значение одновременно, то в результате счет будет увеличен один раз.

2) Грязное чтение - когда одна транзакция меняет данные, а другая их читает, после чего первая откатывается. Например идут две транзакции, пытающиеся снять деньги со счета. На счету 100 рублей, первая пытается снять 30, но откатывается. Вторая пытается снять еще 50, но успевает прочитать значение счета после измененияи до коммита, то есть 70 рублей. В итоге на счету будет 20 рублей.


Почему выделяют такие 2 уровня возможных ошибок?


В том, что от первой можно защититься атомарными операциями, без блокирования и ожидания (wait-free), а для второй уже нужно или блокировать или MVCC городить.
6 окт 14, 18:07    [16667682]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить