Обеспечение целостности данных. Управление транзакциями в СУБД Oracle и SQL Server, страница 4

·  гарантирует, что «писатели» ждут других «писателей» только в том случае, если они пытаются обновлять одни и те же строки одновременно.

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

Когда происходит обновление данных, первоначальные значения данных, изменяемых при обновлении, записываются в сегменты отката буферов базы данных. Все время, пока это обновление остается частью неподтвержденной транзакции, любой пользователь, который пытается читать измененные данные, видит первоначальные значения данных. Только пользователь, который изменяет данные, может видеть их до того, как транзакция подтверждена. Но и сам пользователь,  изменяющий данные, должен видеть их такими, какими они были на момент выполнения команды, если, например, команда читает и изменяет таблицу одновременно. Для создания первоначального образа данных (целостного по чтению) Oracle использует сегменты отката.

По умолчанию Oracle гарантирует целостность чтения на уровне утверждения. Множество данных, возвращаемых одним запросом, согласовано относительно одной и той же точки во времени, пользователь видит данные такими, какими они были перед выполнением запроса:

SQL> SELECT * FROM sample;

ENAME            COMM

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

ALLEN             600

WARD              800

MARTIN           1700

TURNER            300

SQL> UPDATE sample SET comm=comm*1.1

  2  WHERE comm<(SELECT AVG(comm) FROM sample);

SQL> SELECT * FROM sample;

ENAME            COMM

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

ALLEN             660

WARD              880

MARTIN           1700

TURNER            330

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

Если Вы точно знаете, что не собираетесь изменять данные в таблицах, Вы можете выполнить транзакцию «только для чтения» (read-only transaction), начав транзакцию командой SET TRANSACTION READ ONLY. После этого, сколько бы запросов на чтение Вы не выполняли внутри этой транзакции, все они будут согласованы относительно одной и той же точки во времени.

Рассмотрим пример. Пусть первый пользователь выполняет транзакцию «только для чтения»:

SQL> SET TRANSACTION READ ONLY;

Второй пользователь обновляет данные в таблице и подтверждает изменения:

SQL> UPDATE sample SET comm=comm*1.1;

SQL> COMMIT;

SQL> SELECT * FROM sample;

ENAME            COMM

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

ALLEN             660

WARD              880

MARTIN           1870

Несмотря на то, что транзакция подтверждена, первый пользователь видит данные такими, какими они были в тот момент, когда первый пользователь начал транзакцию «только для чтения»:

SQL> SELECT * FROM sample;

ENAME            COMM

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

ALLEN             600

WARD              800

MARTIN           1700

И только после того, как первый пользователь завершит свою транзакцию «только для чтения», он сможет увидеть изменения, подтвержденные вторым пользователем:

SQL> COMMIT;

SQL> SELECT * FROM sample;

ENAME            COMM

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

ALLEN             660

WARD              880

MARTIN           1870

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

Фиксация изменений в базе данных Oracle

Данные базы данных Oracle всегда создаются и обновляются сначала в оперативной памяти, а затем записываются в файлы данных на постоянное хранение.

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

Чтобы защититься от этого, используется механизм записи в журнальные файлы изменений буферов базы данных (Рисунок 1).

·  Данные создаются и обновляются в кэше буферов базы данных

·  Фоновый процесс записи в базу данных DBWR периодически записывает измененные блоки в файлы данных

·  Сервер Oracle записывает все изменения, сделанные в базе данных, в буфер журнала. Записываются непосредственно измененные данные и их адреса в базе данных

·  Фоновый процесс записи в журнал LGWR записывает эту информацию из буфера журнала в текущую группу журнальных файлов на диске в случаях, если: