"На пальцах" - чем отличается "repeatable read" от "read commited" и "read commited snapshot"?

0. Илья Петров (ilya_petrov) 149 07.11.16 08:04 Сейчас в теме
В сети и в книгах довольно много информации с описанием уровней изоляции транзакций, их особенностей и отличий. Когда читаешь - всё вроде понятно, но при столкновении с практическими задачами возникают трудности. Чтобы "пощупать", как ведёт себя система с разными настройками, я сделал элементарный пример с одной единственной таблицей - результаты экспериментов описаны ниже. Дополнительно выяснилось, что система ведёт себя по-разному не только с разными настройками, но и с одинаковыми настройками под разными СУБД (Postgre и MS SQL).

Перейти к публикации

Комментарии
1. Виталий Попов (Сурикат) 149 10.11.16 14:11 Сейчас в теме
А кто-нибудь исследовал чем отличается инструкция (взятая с сайта Гилева):
USE [master]
GO
ALTER DATABASE [Моя База] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE [Моя База]
SET ALLOW_SNAPSHOT_ISOLATION ON

ALTER DATABASE [Моя База]
SET READ_COMMITTED_SNAPSHOT ON
ALTER DATABASE [Моя База] SET MULTI_USER WITH ROLLBACK IMMEDIATE
GO

От того, что есть по умолчанию в 1С в режиме совмести 8.3.6 и выше?
2. Максим Старков (max_st) 10.11.16 15:44 Сейчас в теме
Пробовал, когда нужно было принудительно включить RCSI, но конфигурация была совместима только с 8.2. Работает.
3. Артём Андриянов (CSiER) 11.11.16 04:56 Сейчас в теме
Несколько вопросов по статье:
Собственно, мораль read commited, в нашем случае: чтение данных в транзакции НЕ блокирует их автоматически от записи. Для принудительной блокировки нужно использовать объект БлокировкаДанных.
- разве без БлокировкаДанных это будет не READ UNCOMMITTED?
Для начала конфигурация под MS SQL у нас находится в режиме автоматических блокировок, что соответствует уровню изоляции repeatable read
и ниже
Это и есть иллюстрация "грязного чтения" (dirty read)
- то есть при repeatable read получили dirty read?
• Не увидел ссылку на обработку.
Таким образом, хотя таблица 3.6.2 на стр.41 книги Е.В.Филиппова "Настольная книга 1С:Эксперта по технологическим вопросам" и сообщает нам, что PostgreSQL в режиме управляемых блокировок использует уровень изоляции read commited - этот уровень изоляции в PostgreSQL соответсвует по поведению уровню read commited snapshot в MS SQL.
- книга хорошая, написано верно, ведь Postgre чистый версионник, а ms sql - блокировочник.
4. Максим Кузнецов (Makushimo) 151 11.11.16 06:06 Сейчас в теме
(3) CSiER,
Поддержу вопрос коллеги.
Разве грязное чтение не исчезает на уровне изоляции READ COMMITED и выше?
5. Sergey Andreev (starik-2005) 1135 11.11.16 12:38 Сейчас в теме
В принципе то же самое рассказывают на курсах подготовки к эксперту/профессионалу по тех.вопросам. Единственное, что после курсов вопросы из комментов не возникают. ))
6. Анатолий Бритько (headMade) 134 11.11.16 12:39 Сейчас в теме
(3) CSiER,
Надо разделять менеджер блокировок MSQL и менеджер блокировок 1С.
Когда у вас включен автоматический режим блокировок, то работает только менеджер блокировок MSQL, при этом используется уровень изоляции транзакций repeatable read и serializable.
Причем это не сам MSQL решает какой уровень изоляции использовать при получении данных, а это сервер 1С при передаче запроса на выполнение MSQL "говорит" какой уровень изоляции для какой таблицы необходимо установить. Т.е. тут за блокировку полностью отвечает MSQL.

Когда вы включаете управляемый режим блокировок, то начинает работать менеджер блокировок 1С. И соответственно сервер 1С решает что для MSQL будет достаточным уровень изоляции транзакций read commited т.к. за блокировку данных будет отвечать сам сервер 1С. В этом случае MSQL фактически ничего не блокирует.
А "БлокировкаДанных " - это фактически команда серверу 1С, что необходимо наложить блокировку на определенные данные.
Т.е. не взирая на то используем мы или нет "БлокировкаДанных ", на уровне MSQL всегда будет использоваться read commited.
7. Анатолий Бритько (headMade) 134 11.11.16 12:44 Сейчас в теме
(3) CSiER,
то есть при repeatable read получили dirty read?


В статье же написано про 2 сеанса.
В первом сеансе у нас устанавливается блокировка с уровнем изоляции repeatable read.
А вот ВО ВТОРОМ сеансе у нас будет видно dirty read.

Т.к. в приведенном примере стоит уровень совместимости с 8.2, то read commited snaphot не используется. Соответственно когда пользователь во втором сеансе открывает форму списка, то фактически сервер 1С передает запрос MSQL с хинтом "with no lock". Что фактически означает что будут прочитаны все данные в т.ч. данные не зафиксированных транзакций. Поэтому именно ВО ВТОРОМ сеансе будет наблюдаться грязное чтение, невзирая на то что в первом сеансе на этих записях стоит блокировка с уровнем узоляции repeatable read.
8. Sergey Andreev (starik-2005) 1135 11.11.16 14:17 Сейчас в теме
(6) headMade, а вот г-н Филиппов на курсах, помнится, говорит о том, что блокировки MS SQL все-таки устанавливает. В режиме 8.2 - реад комиттед, в режиме 8.3 - реад комиттед снапшот. В профайлере при этом нет инструкции WITH (NOLOCK), но даже наличие WITH (NOLOCK) не гарантирует их отсутствие.
9. Сергей Носков (Sergey.Noskov) 740 11.11.16 14:34 Сейчас в теме
(1) Сурикат, ничем не отличается, просто 8.3 это делает сама
10. Сан Саныч (herfis) 130 11.11.16 15:03 Сейчас в теме
(8) Вы путаете блокировки с уровнями изоляции транзакций. И блокировки у MSSQL бывают разные, есть много вспомогательных. С практической точки зрения важно то, что в режиме изоляции "реад комиттед снапшот" читающие транзакции не "держат" пишущие транзакции и наоборот. И при этом прочитанные данные всегда согласованы, как при repeatable read.
11. Сан Саныч (herfis) 130 11.11.16 15:31 Сейчас в теме
Ну и да - включение режима "реад комиттед снапшот" по сути меняет поведение MSSQL с "блокировочника" на "версионник". MSSQL начинает фигачить версии изменяемых строк в tempdb и при чтении брать данные подходящих версий оттуда, а не из родных таблиц.
В отличие от старых уровней изоляции - это механизм совершенно другого качества. Поэтому его еще надо явно активировать в свойствах конкретной БД.
12. Артём Андриянов (CSiER) 11.11.16 16:08 Сейчас в теме
(7) headMade, спасибо за ответ, вроде все понятно, но, чувствую, только повторение шагов автора с профайлером окончательно расставят все точки на "и" в моей голове )
13. Анатолий Бритько (headMade) 134 11.11.16 16:17 Сейчас в теме
(8) starik-2005,
помнится, говорит о том, что блокировки MS SQL все-таки устанавливает.

Конечно же блокировки всегда устанавливаются. Важное значение имеет с каким уровнем изоляции они устанавливаются и когда они снимаются.
В некоторых случаях блокировка держится до конца транзакции (при repeatable read), а в некоторых снимается сразу после выполнения запроса (read commited).

но даже наличие WITH (NOLOCK) не гарантирует их отсутствие.
- естественно можно еще рассматривать блокировки стабильности схемы или блокировки намерений, но они на параллельность работы пользователей в 1С никак не влияют.
14. Sergey Andreev (starik-2005) 1135 11.11.16 16:34 Сейчас в теме
(13) лично я вот конкретно на это отвечал:
Когда вы включаете управляемый режим блокировок, то начинает работать менеджер блокировок 1С. И соответственно сервер 1С решает что для MSQL будет достаточным уровень изоляции транзакций read commited т.к. за блокировку данных будет отвечать сам сервер 1С. В этом случае MSQL фактически ничего не блокирует.


А есть такая еще штука, как эскалация блокировок. Может внезапно оказаться, что блокируется вся таблица в SQL, при том 1С вроде как заблокировала только часть данных (до 100к).
15. Сан Саныч (herfis) 130 11.11.16 17:28 Сейчас в теме
(14)
А есть такая еще штука, как эскалация блокировок. Может внезапно оказаться, что блокируется вся таблица в SQL, при том 1С вроде как заблокировала только часть данных (до 100к).

Ну, эти страшилки остались в прошлом, слава богу. Такое было не редкость в режиме автоматических блокировок, где на MSSQL при проведении использовался serializable - самый строгий режим изоляции, беспощадный по блокировкам. В postgresql вообще были табличные блокировки.
А сейчас на версионниках с управляемыми блокировками одинэсник в самом деле фактически самолично управляет блокировками. Я не представляю, что нужно сделать, чтобы спровоцировать экскалацию блокировок СУБД в этой ситуации. Перезаписывать значительную часть большой таблицы в одной транзакции, разве что. Так тогда так и так разница невелика. И то помешает эта эскалация только другим транзакциям на запись.
16. Виталий Попов (Сурикат) 149 11.11.16 23:10 Сейчас в теме
(9) Sergey.Noskov,
1С ставит только SET READ_COMMITTED_SNAPSHOT ON
Хотя на MSDN написано (https://msdn.microsoft.com/ru-ru/library/tcbchxcb(v=vs.110).aspx):
Перед использованием в транзакциях изоляция моментального снимка должна быть включена путем установки параметра базы данных ALLOW_SNAPSHOT_ISOLATION в значение ON. Это приводит к активизации механизма сохранения версий строк во временной базе данных (tempdb).

Собственно вопрос был:
Как работает READ_COMMITTED_SNAPSHOT без ALLOW_SNAPSHOT_ISOLATION?
17. Анатолий Бритько (headMade) 134 12.11.16 10:04 Сейчас в теме
(16) Сурикат,
ссылка нерабочая
18. TMV 14 12.11.16 10:37 Сейчас в теме
(17) headMade, там последние 2 символа зацепило. Вот верная
19. Павел Алексеенко (qwinter) 510 12.11.16 23:36 Сейчас в теме
(15) herfis,
Ну, эти страшилки остались в прошлом, слава богу.

обмен 500 новых контрагентов с 10 дополнительными значениями. Сущий пустяк правда?)
20. Яков Коган (Yashazz) 2119 14.11.16 15:04 Сейчас в теме
А, ещё один пересказ общедоступных источников...
21. Максим Кузнецов (Makushimo) 151 15.11.16 05:40 Сейчас в теме
(20) Yashazz,
Ну не вредничайте.
Статья полезная, а общедоступные источники еще нужно найти и вычитать там именно то что нужно.
Статья хорошая
kuzyara; ilya_petrov; +2 Ответить
22. Сан Саныч (herfis) 130 15.11.16 10:16 Сейчас в теме
(19)
обмен 500 новых контрагентов с 10 дополнительными значениями. Сущий пустяк правда?)

Скорее белиберда какая-то.
23. c+ + (ture) 229 21.12.16 10:06 Сейчас в теме
(19)мильёнами грузим ежедневно. Так что ЭТО пустяк.
Оставьте свое сообщение