Уровни изоляции транзакций

При одновременной работе нескольких клиентов с одной и той же БД возникают проблемы одновременного изменения данных.

Пусть пользователь A получил данные из таблицы RASHOD и впоследствии изменил их. В это же время с той же записью в таблице RASHOD работает пользователь B. Он также изменил записи в той же записи, что и A, и пытается подтвердить их. Пользователь C работает с таблицей RASHOD в режиме «только для чтения». Сразу же возникает группа вопросов:

· Позволять или не позволять B изменять запись, если A еще не подтвердил ее изменение?

· Позволять ли C видеть изменения, внесенные A и B?

· Может ли A видеть изменения, внесенные B, и наоборот?

Для разрешения указанных проблем на стороне клиента определены три уровня изоляции (разграничения) транзакций.

При уровне изоляции транзакций Dirty Read («грязное чтение») конкурирующие транзакции видят изменения, внесенные, но не подтвержденные текущей транзакцией. Если текущая транзакция откатит сделанные изменения, другие транзакции будут обладать недостоверными данными. Этот уровень изоляции может привести к серьезным ошибкам и применяется крайне редко – фактически он не изолирует конкурирующие транзакции.

При уровне Read Committed («подтвержденное чтение») конкурирующие транзакции работают с данными, какими они были на момент старта транзакции A. однако, если транзакция A внесла изменения в запись и подтвердила их, а незавершенная транзакция вновь прочитала эти данные, она увидит изменения.

Уровень изоляции Repetable Read («повторяющееся чтение») заставляет конкурирующие транзакции оперировать с собственными (локальными) версиями одной и той же записи. Если транзакция A читает какую-то запись, она, как и при уровне ReadCommited, получит последнюю подтвержденную ее версию. Однако, если другая транзакция изменит эту запись, а транзакция A вновь прочитает ее, она не увидит внесенных изменений, т.е. A видит всегда одну и ту же версию записи. Изменения, которые вносят конкурирующие транзакции в одну и ту же запись, могут конфликтовать. В этом случае фактически изменит данные первая завершенная транзакция, а попытки подтвердить свои изменения второй и всеми другими незавершенными транзакциями, изменившими те же записи, будут отвергнуты.

Разные серверы БД различным образом интерпретируют уровни изоляции транзакций.

 

Сервер БД Уровень изоляции Интерпретируется как
Oracle Dirty Read Read Committed Repetable Read Read Committed Read Committed Repetable Read
MS SQL Server, Sybase Dirty Read Read Committed Repetable Read Read Committed Read Committed Не поддерживается
DB2 Dirty Read Read Committed Repetable Read Dirty Read Read Committed Repetable Read
Informix Dirty Read Read Committed Repetable Read Dirty Read Read Committed Repetable Read
InterBase Dirty Read Read Committed Repetable Read Read Committed Read Committed Repetable Read
Несерверные СУБД Dirty Read Read Committed Repetable Read Dirty Read Не поддерживается Не поддерживается

 

Для InterBase с учетом управляющих параметров формат оператора начала транзакции выглядит следующим образом:

SET TRANSACTION [ имя транзакции ]

[READ WRITE | READ ONLY]

[WAIT | NO WAIT]

[[ISOLATION LEVEL] {SNAPSHOT [TABLE STABILITY]

| READ COMMITTED [[NO] RECORD_VERSION]}]

------------------------------

· READ WRITE | READ ONLY WAIT – устанавливает уровень доступа к данным (по умолчанию READ WRITE )

· WAIT | NO WAIT – определяет поведение при возникновении конфликта при обновлении записи данной транзакции с другой транзакцией, ранее сделавшей изменение в той же записи: WAIT (по умолчанию) побуждает данную транзакцию ожидать завершения конкурирующей транзакции; NO WAIT определяет аварийное завершение данной транзакции.

· ISOLATION LEVEL – определяет уровни изоляции транзакций на сервере (по умолчанию SNAPSHOT, что соответствует уровню REPETABLE READ.

· READ COMMITTED разрешает стартующей транзакции читать только подтвержденные записи: NO RECORD_VERSION (по умолчанию) – читается последняя версия записи, даже если она не подтверждена другой транзакцией; при этом если указан параметр WAIT, стартующая транзакция будет ожидать подтверждения последней версии; RECORD VERSION – читается последняя подтвержденная версия записи.

 

Пример.

SET TRANSACTION WAIT

ISOLATION LEVEL READ COMMITTED