Работа SQL со множеством пользователей.
Транзакция (transaction) - это группа операций над данными, которые либо выполняются все, либо все вместе отменяются. Сердцевиной и основой эффективности функционирования многопользовательских систем клиент-сервер является эффективное управление транзакциями. Собственно само понятие транзакции возникло именно в процессе исследования принципов построения и функционирования централизованных многопользовательских реляционных СУБД
Помимо обеспечения целостности данных механизм транзакций оказался чрезвычайно полезным для практической реализации одного из основополагающих принципов распределенных многопользовательских систем - изолированности пользователей. Единичные действия пользователей с базой данных ассоциированы с транзакциями. В том случае, когда от разных пользователей поступают транзакции, время выполнения которых перекрывается, монитор транзакций обеспечивает специальную технологию их взаимного выполнения и изоляции с тем, чтобы избежать нарушений согласованного состояния данных и других издержек совместной обработки. К числу подобных издержек относятся:
· потерянные изменения;«грязные данные»;неповторяющиеся чтения.
Потерянные изменения возникают тогда, когда две транзакции одновременно изменяют один и тот же объект базы данных.
«Грязные данные» - возникают тогда, когда одна транзакция изменяет какой-либо объект данных, а другая транзакция в этот момент читает данные из того же объекта.
Неповторяющиеся чтения возникают тогда, когда одна транзакция читает какой-либо объект базы данных, а другая до завершения первой изменяет и успешно фиксируется
Существуют два различных подхода сериализации транзакций:
- синхронизационные захваты (блокировки) объектов базы данных;
- временные метки объектов базы данных.
В первом подходе определяется два основных режима захватов - совместный режим (Shared) и монопольный режим (exclusive). При совместном режиме осуществляется разделяемый захват, требующий только операций чтения. Поэтому такой захват еще называют захватом по чтению.
При построении сериальных планов допускается совмещение только захватов по чтению. В остальных случаях транзакции должны «ждать», когда необходимые объекты разблокируются (освободятся). Более изощренные стратеги сериализации транзакций основываются на «гранулировании» объектов захвата (файл базы данных, отдельная таблица, страница файла данных, отдельная запись-кортеж). Соответственно при этом расширяется номенклатура синхронизационных режимов захватов, например в совместном режиме (по чтению может быть захвачен в целом файл и отдельные его страницы, или в другом случае обеспечивается совместный режим захвата файла с возможностью монопольного захвата отдельных его объектов - таблиц, страниц или записей-кортежей). Грануляция синхронизированных блокировок позволяет строить более эффективные планы сериализации транзакций.
Существенным недостатком синхронизационных захватов является возможность возникновения тупиковых ситуаций (Deadlock). Предположим, одна транзакция на первой фазе установила монопольный захват одного объекта, а другая транзакция монопольный захват второго объекта. Для осуществления полного набора своих операций первой транзакции еще требуется совместный захват второго объекта, а второй транзакции, соответственно, совместный захват первого объекта. Ни одна из транзакций не может закончить первую фазу, т.е. полностью накопить все необходимые захваты, так как требуемые объекты уже монопольно захвачены, хотя были свободными к моменту начала осуществления транзакций.
Непростой проблемой является автоматическое обнаружение (распознавание) таких тупиковых ситуаций и их разрешение (разрушение). Распознавание тупиков основывается на построении и анализе графа ожидания транзакций, состоящего из вершин- транзакций и вершин-объектов захвата. Исходящие из вершин- транзакций дуги к вершинам-объектам соответствуют требуемым захватам, а дуги, исходящие из вершин-объектов к вершинам- транзакциям соответствуют полученным захватам.
Еще одной проблемой является технология, или, лучше сказать, алгоритм разрушения тупиков. В общем плане такие алгоритмы основываются на выборе транзакции-жертвы, которая временно откатывается для предоставления возможности завершения выполнения операций другими транзакциями, что, конечно же, в определенной степени нарушает принцип изолированности пользователей. В качестве «жертвы» выбирается или самая «дешевая» транзакция в смысле затрат на выполнение, или транзакция с наименьшим приоритетом.
Предотвращение несанкционированного доступа к данным является серьезной проблемой, которая решается разными способами. Самый простой - это парольная защита либо всей таблицы, либо некоторых ее полей (такой механизм поддерживается, например, в Corel Paradox).
В настоящее время более популярен другой способ защиты данных - создание списка пользователей (users) с именами (user names) и паролями (passwords). В этом случае любой объект базы данных принадлежит конкретному пользователю, и этот пользователь предоставляет другим пользователям разрешение на чтение или модификацию данных из этого объекта либо на модификацию самого объекта. Этот способ применяется во всех серверных и некоторых настольных СУБД (например, Microsoft Access).
Некоторые СУБД, в основном серверные, поддерживают не только список пользователей, но и роли (roles). Роль - это набор привилегий. Если конкретный пользователь получает одну или несколько ролей, то вместе с ними - и все привилегии, определенные для данной роли.
Любая реляционная СУБД, поддерживающая списки пользователей и ролей, должна их где-то хранить. В дополнение к этим спискам многие СУБД хранят списки таблиц, индексов, триггеров, процедур и др., а также сведения о том, кто ими владеет. Эти списки называются системными таблицами (system tables), а соответствующая часть базы данных называется системным каталогом (system catalog). Отметим, что не все СУБД поддерживают системные каталоги (например, их не поддерживают такие популярные в недавнем прошлом СУБД, как dBase и Paradox).