Наличие открытой транзакции само по себе почти не будет иметь последствий. Простой
BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT
в худшем случае будет содержать несколько байтов значений состояния. Ничего страшного.
Большинство программ будут выполнять реальную работу в рамках транзакции, и это другой вопрос. Смысл транзакции заключается в том, что вы можете быть уверены, что несколько фактов в базе данных верны одновременно, несмотря на то, что другие пользователи одновременно пишут в одну и ту же базу данных.
Возьмите канонический пример перевода денег между банковскими счетами. Система должна гарантировать, что исходный счет существует, имеет достаточные средства, целевой счет существует, и что дебет и кредит происходят или не происходят. Это должно гарантировать это, когда происходят другие транзакции, возможно, даже между этими двумя учетными записями. Система обеспечивает это, блокируя соответствующие таблицы. То, какие блокировки приняты, и сколько работы других людей вы видите, контролируется уровнем изоляции транзакций .
Поэтому, если вы выполняете большую работу, есть большая вероятность, что другие транзакции будут поставлены в очередь в ожидании объектов, на которых вы держите блокировки. Это уменьшит общую пропускную способность системы. В конце концов они достигнут пределов времени ожидания и потерпят неудачу, что является проблемой для общего поведения системы. Если вы используете оптимистический уровень изоляции, ваша транзакция может потерпеть неудачу, когда вы пытаетесь выполнить коммит из-за работы других.
Удержание замков забирает системные ресурсы. Это память, которую система не может использовать для обработки других запросов, что снижает пропускную способность.
Если была проделана большая работа, система может выбрать повышение блокировки . Вместо блокировки отдельных строк вся таблица будет заблокирована. Тогда будет затронуто больше одновременно работающих пользователей, пропускная способность системы будет снижаться, а влияние приложения будет выше.
Изменения данных записываются в файл журнала, как и блокировки, которые их защищают. Они не могут быть удалены из журнала до фиксации транзакции. Следовательно, очень длинная транзакция может вызвать переполнение файла журнала и связанные с ним проблемы.
Если текущая работа использует базу данных tempdb, что, вероятно, для больших рабочих нагрузок, ресурсы могут быть связаны до конца транзакции. В крайних случаях это может привести к сбою других задач, потому что для них больше нет места. У меня были случаи, когда плохо закодированная UPDATE заполняла базу данных tempdb, поэтому для сортировки отчета оставалось недостаточно диска, и отчет не удался.
Если вы выберете ОТКРЫТЬ транзакцию, или система выйдет из строя и восстановится, время, необходимое для того, чтобы система снова стала доступной, будет зависеть от того, сколько работы было выполнено. Простая открытая транзакция не повлияет на время восстановления, а на объем выполненной работы. Если транзакция была открыта, но простояла час, восстановление будет практически мгновенным. Если он писал постоянно в течение этого часа, эмпирическое правило таково, что время восстановления также будет около часа.
Как видите, длительные транзакции могут быть проблематичными. Для систем OLTP рекомендуется использовать одну транзакцию базы данных на одну бизнес-транзакцию. Для пакетного ввода процесса работы в блоках, с частыми коммитами и перезапуском логической кодировки Обычно несколько тысяч записей могут быть обработаны в одной транзакции БД, но это следует проверить на предмет параллелизма и потребления ресурсов.
Не поддавайтесь искушению перейти в другую крайность и полностью избегать транзакций и блокировок. Если вам необходимо поддерживать согласованность ваших данных (и зачем вам использовать базу данных?), Уровни изоляции и транзакции служат очень важной цели. Узнайте о своих возможностях и решите, с каким балансом параллелизма и правильности вы готовы жить для каждой части вашего приложения.