Контроль версий строк

167 Исходники баз данных

Компонент Database Engine поддерживает механизм управления оптимистической параллельной работы, который основан на управлении версиями строк. При модифицировании данных с использованием управления версиями строк, для всех выполняемых в базе данных модификаций данных создаются и поддерживаются логические копии данных. При каждой модификации строки система баз данных сохраняет в системной базе данных tempdb исходный вид записи ранее зафиксированной строки. Каждая версия строки помечается порядковым номером транзакции (XSN - transaction sequence number), которая выполнила это изменение. (Порядковый номер транзакции XSN применяется для уникальной идентификации транзакций.)

Самая последняя версия строки всегда сохраняется в базе данных и соединяется в связанном списке с соответствующей версией, сохраненной в базе данных tempdb. Старая версия строки в базе данных tempdb может содержать указатели на другие, еще более старые версии. Каждая версия строки сохраняется в базе данных tempdb до тех пор, пока существуют операции, для которых она может потребоваться.

Управление версиями строк изолируют транзакции от эффектов модификаций, выполненных другими транзакциями, без необходимости запрашивать разделяемые блокировки прочитанных строк. Это значительное уменьшение общего количества блокировок, устанавливаемых на этом уровне изоляции, существенно повышает степень доступности данных. Но использование монопольных блокировок все равно требуется: транзакции, использующие оптимистический уровень изоляции SNAPSHOT, запрашивают блокировки, когда они модифицируют строки.

Управление версиями строк, помимо прочего, применяется для:

Уровень изоляции READ COMMITTED SNAPSHOT

Уровень READ COMMITED SNAPSHOT является облегченным вариантом уровня изоляции READ COMMITTED, рассмотренного в предыдущей статье. Это изоляция на уровне инструкции, что означает, что любая другая транзакция будет читать зафиксированные значения в том виде, в каком они существуют на момент начала этой инструкции. Для выборки строк для обновлений этот уровень изоляции возвращает версии строк в фактические данные и устанавливает на выбранных строках блокировки обновлений. Реальные строки данных, которые требуется изменить, получают монопольные блокировки.

Основным преимуществом уровня изоляции READ COMMITED SNAPSHOT является то, что операции чтения не блокируют обновлений, а обновления не блокируют операций чтения. Но с другой стороны, обновления блокируют другие обновления, поскольку для выполнения операций обновления устанавливаются монопольные блокировки.

Уровень изоляции READ COMMITED SNAPSHOT разрешается посредством предложения SET в инструкции ALTER DATABASE. После активирования этого уровня изоляции никаких дополнительных изменений выполнять не требуется. Любая инструкция, для которой указан уровень изоляции READ COMMITTED, теперь будет выполняться на уровне READ COMMITED SNAPSHOT.

Уровень изоляции SNAPSHOT

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

Транзакции уровня изоляции SNAPSHOT получают монопольные блокировки на данные перед тем, как выполнять изменения только с целью принудительного обеспечения ограничений. В противных случаях данные не блокируются до тех пор, пока данные не требуется изменить. Когда строка данных удовлетворяет критериям обновления, транзакция уровня изоляции SNAPSHOT проверяет, не была ли эта строка данных изменена и подтверждены изменения данных этой строки в конкурентной транзакции после того, как была запущена текущая транзакция. Если строка данных была изменена параллельной конкурентной транзакцией, то возникает конфликт обновления и дальнейшее выполнение транзакции уровня изоляции SNAPSHOT завершается. Этот конфликт обновления обрабатывается системой баз данных, поэтому способа отключить функцию обнаружения конфликтов обновления не существует.

Разрешение уровня изоляции SNAPSHOT осуществляется в два шага. Сначала на уровне базы данных включается опция базы данных ALLOW_SNAPSHOT_ISOLATION (это можно сделать, например, посредством среды Management Studio). После этого для каждого сеанса, который будет использовать этот уровень изоляции, нужно для инструкции SET TRANSACTION ISOLATION LEVEL задать значение SNAPSHOT. Когда эти опции установлены, будут создаваться версии для всех строк, изменяемых в базе данных.

Разница между уровнями изоляции READ COMMITTED SNAPSHOT и SNAPSHOT

Самое важное различие между этими двумя оптимистическими уровнями изоляции состоит в том, что при уровне SNAPSHOT возможны конфликты обновлений, когда процесс работает с одними и теми же данными во время выполнения транзакции и не является заблокированным. В противоположность этому, уровень изоляции READ COMMITTED SNAPSHOT не использует свой собственный порядковый номер транзакции XSN при выборе версий строк. Каждый раз при запуске инструкции такая транзакция считывает самый последний порядковый номер транзакции XSN, выданный для данного экземпляра системы баз данных, и выбирает строку с этим номером.

Другое отличие состоит в том, что уровень изоляции READ COMMITED SNAPSHOT позволяет другим транзакциям изменять данные до того, как будет завершена транзакция типа управления версиями строк. Это может вызвать конфликт, если в период времени между выполнением операции чтения транзакцией типа управления версиями строк и последующей попыткой этой транзакции выполнить соответствующую операцию записи данные были изменены другой транзакцией. (Для приложений на основе уровня изоляции SNAPSHOT система выявляет возможность конфликта и выдает соответствующее сообщение об ошибке.)

Пройди тесты
Лучший чат для C# программистов