Явные транзакции при обновлении данных

Что-то я часто стал писать про SQL. Наверно потому, что очень много интересных вещей с ним замечаю. Недавно наткнулся на модуль на работе, где любая операция округлялась в явную транзакцию. Не понял, нафига это нужно, когда любая модификация данных итак автоматически запихивается в неявную транзакцию. От явности в банальных операциях UPDATE кажется толку нету. Даже если ты не написал begin transaction, операция все равно в случая ошибки откатывается полностью, а не с того места, где запрос закончил обновление.

Явные транзакции реально необходимы только там, где выполняется несколько операций изменения данных, и эти несколько операций должны быть единым целым. Второе условие очень важно и создавать лишние блокировки на сервере не стоит, потому что каждая транзакция не бесплатна для базы данных и кушает достаточно ресурсов, особенно на MS SQL Server. В этом отношении Oracle намного более щедрый к ресурсам, о чем я уже писал.

Я бы советовал каждый раз подумать - а действительно ли нужна здесь транзакция? Например, на вашем сайте есть форум. На посещаемых форумах идет большое количество трафа и запросов на выборку данных. Если вы используете MS SQL Server, то он по умолчанию блокирует выборку данных, если данные заблокированы на изменения в чужой транзакции (вот убейте меня, но не могу понять нафига и почему не сделают версионность данных как единственный возможный вариант изоляции). И слава богу, если у вас есть возможность переключить уровень изоляции, но не все провайдеры позволяют сделать это.

Итак, все реализации форумов, которые я видел состоят из множества таблиц. Топики очень часто помещают в одну таблицу, а ответы в другую. Еще куча таблиц может задействоваться для различной дополнительной информации. Когда пользователь создает новый топик, то конечно же хотелось бы код форума сохранил данные во все таблицы, и если что-то произошло не так, то откатывал все нафиг и не мусорил в базе. Это легко решается, обрамлением всех запросов изменения данных в базе в одну транзакцию.

Каждая транзакция - это блокировка и при большой посещаемости количество блокировок растет как плесень и ведет себя как плесень, блокируя данные на чтение. Блокировки становятся поводом тому, что ситуации с проблемами добавления/изменения данных становяться боле частым гостем на сервере. Выгода? Вы спасаетесь от сомнительного мусора, который никому не мешает за счет потери ресурсов.

Без транзакций возникает вероятность потери целостности данных из-за того, что один запрос сохранил данные в таблицу топика, но не сохранил данные в таблицу с текстом (комментарием). Хуже, когда наоборот, но это бывает когда народ тупо использут try блоки для того, чтобы тупо глушить любые исключительные ситуации и никак на это не реагируют. Таблицы форума не на столько важная информация, чтобы обновлять их в транзакциях. Стоит их убрать и вы осободите сервер от личней нагрузки, количество блокировок уменьшится и исключительные ситуации снизятся.

А что же делать с мусором, когда данные сохранились в одной таблице, а в другой нет? Тут главное не тупить с блоками try и банально использовать внешние индексы. Некоторые почему-то боятся их из-за проблем с удалением данных. Программисты не любят, когда нужно чистить подчиненную таблицу только из-за того, что нужно удалить одну строку из главной таблицы. Но вот как раз вот такие случаи наводят в базе данных на много больше мусора, чем отсутствие транзакций.

Лично я считаю, что лучше использовать связи, чем транзакции для защиты данных от мусора. Ну а транзакции использовать только там, где они реально нужны и где данные критичны. Ну а тем более их нельзя использовать в тех случаях, когда идет обновление данных, да еще и не связанных между собой. Это абсолютно не нужная и даже вредная блокировка. Во всех банальных изменениях данных доверьтесь неявным блокировкам.


Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым


Комментарии

Гость

21 Мая 2010

Здравствуйте!
я работаю с ms sql server 2005.
Буквально на днях я увидела процедуру загрузки пакета (написана фирмой которая нас обслуживает), которая состояла из большой транзакции, которая влючала в себя 10 Insert + > 30 delete, запуск нескольких функций по удалению временных таблиц и собственно созданию этих таблиц.
При этом нагрузка на проц была ~ 96%:(


Добавить Комментарий

Еще что-нибудь

Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

Без проблем вступаю в неразборчивые разговоры по e-mail. Стараюсь отвечать на письма всех читателей вне зависимости от страны проживания, вероисповедания, на русском или английском языке.

Пишите мне