Страница 14 из 27
Изоляция транзакций Изоляция означает, что параллельно выполняющиеся транзакции не могут пересекаться друг с другом. Кроме всего прочего, это означает, что ни одна транзакция не может видеть неподтвержденные другой транзакцией данные (иногда это также называется dirty read). Не все СУБД это предписывают, но InterBase/Firebird так делает, причем по умолчанию — всегда. Одно из важнейших последствий такого принципа работы состоит в том, что клиент должен запустить запрос, получить строки данных и завершить выполнение инструкций в контексте одной транзакции. Без указания транзакции запрос выполнить невозможно, так как сервер тогда просто не будет знать, какую версию записи транзакция должна видеть. Существует несколько уровней изоляции транзакций, но наиболее часто используемый уровень — read committed (читать только подтвержденные) и snapshot (снимок). В первом случае запрос возвращает записи именно в таком виде, в каком они существуют на момент выполнения запроса, даже если они будут переданы клиенту значительно позже. Во втором случае запрос возвращает состояние записей на момент старта транзакции, даже если сам запрос был выполнен значительно позже. То есть, если Вася стартует транзакцию с уровнем read committed и выбирает все записи из таблицы, но не все записи передаются ей в клиентское приложение, а Петя в этот момент удаляет одну из записей и завершает транзакцию, запрос Васи должен возвратить удаленную Петей запись, как только запрос Васи наконец-то передает ее в приложение, даже если эта запись была передана уже после того, как Петя ее удалил. Если бы набор данных Васи не включал удаленной Петей записи, получилось бы, что транзакции Пети и Васи пересеклись, и изоляция была нарушена. Последнее приводит к тому, что транзакция Васи транзакцией, грубо говоря, называться не может. Вот почему SELECT-запросы, как и все остальные, следует использовать в контексте транзакций, и вот почему нельзя получить часть данных в транзакции, завершить ее, а затем продолжить получение информации из набора данных. Причем нет никакого способа предписывать уровни изоляции без механизма транзакций. Теперь о том, зачем вообще заботиться об изоляции транзакций. Когда к таблицам могут одновременно обращаться сотни пользователей, должен быть способ точно и ясно определить, что видит каждая из транзакций. Вы нуждаетесь в возможности связывания одного набора данных с другим, а этого нельзя сделать, если набор данных может изменяться в какое-то время между собственно выборкой и передачей его клиенту. |