Понимание SQL
Шрифт:
Визуально, среда базы данных, это картина которая постоянно отображает для существующих пользователей, постоянно вводимые и изменяемые данные, допуская, что если система правильно разработана, она будет функционировать без сбоев. Однако реально, благодаря человеческим или компьютерным сбоям, ошибки время от времени случаются, и поэтому хорошие компьютерные программы стали применять способы отмены действий вызвавших такие ошибки. Команда SQL, которая воздействует на содержание или структуру базы данных - например команда модификации DML или команда DROP TABLE, - не обязательно будет необратимой. Вы можете определить после окончания ее действия, останутся ли изменения сделанные данной командой или группой команд постоянными в базы данных, или онибудут полностью проигнорированы. С этой
COMMIT WORK;
Синтаксис отмены изменения -
ROLLBACK WORK;
В большинстве реализаций, вы можете установить параметр, называемый AUTOCOMMIT. Он будет автоматически запоминать все действия которые будут выполняться. Действия которые приведут к ошибке, всегда будут автоматически "прокручены" обратно. Если это предусмотрено в вашей системе, для фиксации всех ваших действий, вы можете использовать эту возможность с помощью команды типа:
SET AUTOCOMMIT ON;
Вы можете вернуться к обычной диалоговой обработке запросов с помощью такой команды:
SET AUTOCOMMIT OFF;
Имеется возможность установки AUTOCOMMIT которую система выполнит автоматически при регистрации. Если сеанс пользователя завершается аварийно - например, произошел сбой системы или выполнена перезагрузка пользователя, - то текущая транзакция выполнит автоматический откат изменений. Это - одна из причин, по которой вы можете управлять выпонением вашей диалоговой обработки запросов, разделив ваши команды на большое количество различных транзакций. Одиночная транзакция не должна содержать много несвязанных команд; фактически, она может состоять из единственной команды. Транзакции которые включают всю группу несвязанных изменений не оставляют вам фактически никакого выбора сохранить или отклонить целую группу, если вы хотите отменить только одно определенное изменение. Хорошим правилом которому надо следовать, это делать ваши транзакции состоящими из одной команды или нескольких близко связанных команд. Например, предположим вы хотите удалить продавца Motika из базы данных. Прежде, чем вы удалите его из таблицы Продавцов, вы сначала должны сделать что-нибудь с его порядками и его заказчиками. (Если используются ограничения внешнего ключа, и ваша система, следуя ANSI, ограничивает изменение родительского ключа, у вас не будет выбора делать или не делать этого. Это будет сделано обязательно.)
Одно из логических решений, будет состоять в том, чтобы установить поле snum в его порядках в NULL, в следствии чего ни один продавец не получит комиссионные в этих порядках, пока комиссионые не будут предоставлены заказчикам для Peel. Затем вы можете удалить их из таблицы Продавцов:
UPDATE Orders
SET snum=NULL
WHERE snum=1004;
UPDATE Cudomers
SET snum=1001
WHERE snum=1004;
DELETE FROM Salespeople
WHERE snum=1004;
Если у вас проблема с удалением Motika (возможно имеется другой внешний ключ ссылающийся на него о котором вы не знали и не учитывали ), вы могли бы отменить все изменения которые вы сделали, до тех пор пока проблема не будет определена и решена.
Более того, это должна быть группа команд, чтобы обрабатывать ее как одиночную транзакцию. Вы можете предусмотреть это с помощью команды COMMIT, и завершить ее с помощью команды COMMIT или ROLLBACK.
КАК SQL ОБЩАЕТСЯ СРАЗУ СО МНОГИМИ ПОЛЬЗОВАТЕЛЯМИ
SQL часто используется в многопользовательских средах - в средах, где сразу много пользователей могут выполнять действия в базе данных одновременно. Это создает потенциальную возможность конфликта между различными выполняемыми действиями. Например, предположим что вы выполняете команду в таблице Продавцов :
UPDATE Salespeople
SET comm=comm * 2
WHERE sname LIKE 'R%';
и в это же время, Diane вводит такой запрос:
SELECT city, AVG (comm)
FROM Salespeople
GROUP BY city;
Может ли усредненное значение(AVG) Diane отазить изменения которые вы делаете в таблице? Не важно, будет это сделано или нет, а важно что бы были отражены или все или ни одно из значений комиссионных (comm) для которых выполнялись изменения. Любой промежуточный результат является случайным или непредсказуемым, для порядка в котором значения были изменены физически. Вывод запроса, не должен быть случайным и непредсказуемым. Посмотрим на это с другой стороны. Предположим, что вы находите ошибку и прокручиваете обратно все ваши модификации уже после того, как Diane получила их результаты в виде вывода. В этом случае Diane получит ряд усредненых значений основанных на тех изменениях которые были позже отменены, не зная что ее информации неточна. Обработка одновременных транзакций называется - параллелизмом или совпадением, и имеет номера возможных проблем которые могут при этом возникать.
Имеются следующие примеры:
* Модификация может быть сделана без учета другой модификации. Например, продавец должен сделать запрос к таблице инвентаризации, чтобы найти десять фрагментов пунктов торговцев акциями, и упорядочить шесть из их для заказчика. Прежде, чем это изменение было сделано, другой продавец делает запрос к таблице и упорядочивает семь из тех же фразментов для своего заказчика. ПРИМЕЧАНИЕ: Термин "упорядочить", аналогичен общепринятому - "заказать", что в принципе более соответствует логике запроса, потому что с точки зрения пользователя, он именно "заказывает" информацию в базе данных, которая упорядочивает эту информацию в соответствии с "заказом".
* Изменения в базе данных могут быть прокручены обратно уже после того, как их действия уже были закончены. Например если Вы отменили вашу ошибку уже после того, как Diane получила свой вывод.
* Одно действие может воздействовать частично на результат другого действия. Например когда Diane получает среднее от значений в то время как вы выполняете модификацию этих значений. Хотя это не всегда проблематично, в большинстве случаев действие такое же как если бы агрегаты должны были отразить состояние базы данных в пункте относительной стабильности. Например в ревизионных книгах, должна быть возможность вернуться назад и найти это существующее усредненное значение для Diane в некоторой временной точке, и оставить его без изменений которые можно было бы сделаны начиная уже с этого места. Это будет невозможно сделать, если модификация была выполнена во время вычисления функции.
* Тупик. Два пользователя могут попытаться выполнить действия которые конфликтуют друг с другом. Например, если два пользователя попробуют изменить и значение внешнего ключа и значение родительского ключа одновременно.
Имеется много сложнейших сценариев которые нужно было бы последовательно просматривать, если бы одновременные транзакции были неуправляемыми. К счастью, SQL обеспечивает вас средством управления параллелизмом для точного указания места получения результата. Что ANSI указывает для управления параллелизмом -это что все одновременные команды будут выполняться по принципу - ни одна команда не должна быть выдана, пока предыдущая не будет завершена (включая команды COMMIT или ROLLBACK ).