Как стать автором
Обновить

Транзакция, ACID, CAP теорема и уровни изоляций транзакций простыми словами

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров23K
Всего голосов 45: ↑39 и ↓6+37
Комментарии14

Комментарии 14

Вспоминая старые времена, когда передний край ИТ крутился вокруг СУБД и тонкостей реализации в них поддержки уровней изоляции, то хорошо бы в статье написать про обратную сторону медали - какими решениями и технологиями СУБД обеспечивает это все: Вспоминается варианты наложения блокировок: table level lock, page level lock, row level lock и их эскалация. Как они хранятся (в памяти, на диске)

Типы блокировок: shared (READ|UPDATE), Intent, Exclusive и животворящий deadlock

И в конце рассказать, почему в итоге гонку технологий выиграла snapshot isolation и все промышленные субд которые не поддерживали ее так или иначе проиграли (DB2, informix, sybase ase).

Помню, какие были жаркие споры в начале 200х на sql.ru по поводу клссмических блокировчников и версионников и их работы на ресурсах серверов того времени. Ностальгия.

Статья получилась бы намного большой в объеме и сложной в написании

*бОльшей

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

Dirty Read - чтение незафиксированных изменений значений.

Non-repeatable Read - чтение зафиксированных изменений значений.

Phantom Read - чтение зафиксированных изменений набора.

Чтение незафиксированных изменений набора - ???

Вы явно пишете:

  • в неповторяющемся чтении учитываются лишь завершённые транзакции.

Соответственно вопрос - а что, чтение незафиксированных изменений набора вообще невозможно? никогда и ни при каких обстоятельствах? Уж коли оно вообще нигде не "посчитано"..

Non-repeatable Read это когда вы читаете одну и туже строку два раза подряд, но из-за конкурирующей транзакции, которая меняет значение в этой строке, второе чтение может вернуть значения в строке, отличные от первого чтения.

Phantom Read - это когда вы читаете набор из нескольких строк опять таки два раза, но из-за конкурирующей транзакции, которая может удалить или изменить одну из строк так, что она уже не попадает под условия выборки, то после второго чтения результирующий набор будет отличаться от первого.

В обеих случаях читаются только закомичченные данные, но влияние на результат отличается.

Вот тут детально: https://stackoverflow.com/questions/11043712/non-repeatable-read-vs-phantom-read

"Non-repeatable reads are when your transaction reads committed UPDATES from another transaction. The same row now has different values than it did when your transaction began.

Phantom reads are similar but when reading from committed INSERTS and/or DELETES from another transaction. There are new rows or rows that have disappeared since you began the transaction."

Не надо мне это объяснять, я в курсе. Я указываю на погрешность статьи и вопрос, который легко может возникнуть у читателя и ответ на который в статье отсутствует. Вставленные, но не зафиксированные записи МОГУТ быть получены в параллельной транзакции. И вы должны это явно указать.

Если вы только пользуетесь чужими текстами и пока не знаете, когда это возможно - ну поэкспериментируйте, в конце-то концов.

@AlexeyK77Ну вообще же ребята неверно. Откуда только что берете? Во - первых, не "Phantom read", а "Phantom". Это уже потом выводится, что "Phantom" это "read"
Во - вторых, "NON-repeatable read" это про Update/Delete.
"Phantom" это "INSERT"
Все эти определения идут от Стандарта ISO/IEC 9075, согласно нему(стр84):
P2 (‘‘Non-repeatable read’’): SQL-transaction T1 reads a row. SQL-transaction T2 then modifies or deletes that row
P3 (‘‘Phantom’’): SQL-transaction T1 reads the set of rows N that satisfy some . SQL-transaction T2 then executes SQL-statements that generate one or more rows

Consistency (Согласованность) — принцип, согласно которому база данных гарантирует, что после успешного завершения каждой транзакции, данные в ней остаются в согласованном состоянии. Другими словами, до и после выполнения транзакции данные остаются надёжными и достоверными. Например, в контексте банковского перевода это означает, что транзакция не приведёт к появлению отрицательного баланса на одном счете, и одновременно к положительному на другом. Таким образом, мы можем быть уверены в достоверности и корректности данных в базе.

А что мне мешает в одной (например pg) транзакции сделать две операции, которые загонят по одному счёту плюс, а по другому минус? Я нарушу принципы ACID?

Такой ответ часто приходится слышать, но это скорее демонстрация непонимания, что есть на самом деле неконсистентность ACID.

Если совсем простыми словами, то Consistency (ACID) обеспечивает гарантию, что в базе не будут нарушены ограничения (constraints). Например, не сможете затолкать в одну таблицу две записи с одним значением первичного ключа.

НЛО прилетело и опубликовало эту надпись здесь

По мне так вся эта статья набор баззвордов. Лучше бы про RowVersion(timestamp) и инвалидацию кеша в ORM написали

Ну ладно согласованность неправильно описали. Но кап теорема вообще не имеет отношения к бд, как таковой. Если у вас бд находится на одной машине - то она всегда удовлетворяет кап теореме. А вот если у вас несколько инстансов чего угодно (кеша, бд, вычислительных мощностей) разнесены сетью - тогда вступает в действие кап теорема. Она всегда о разделении сетью. А без P - CA (в рамках CAP) не имеют смысла

Вот только это ушло в прошлое с появлением mvcc

Плохо, что нет конкретных примеров. А без примеров это все болтология - на собесах тоже часто спрашивают про уровни изоляции. Но главное, это когда до примеров доходит. Объяснить не могут, в каких случаях нужно какой уровень применять, при какой бизнес - логике. Теория это одно, практика - совсем другое

И по поводу «снижения производительности». Тоже примеров нет - когда, на сколько? Есть специализированные benchmark -инструменты, вроде pgbench, есть универсальные, вроде HammerDB. Конкретика и примеры - вот что было бы интересно почитать

На MSSQL всегда использовал по умолчанию READ Commited и проблем никогда не было. В последнем случае сделал даже межпрограммное общение через БД. Но вся логика в хранимых процедурах, как и транзакции. Никаких триггеров, view и прочих лишних ненужных сущностей с недетерминированным поведением.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий