Неплохая практика всегда создавать транзакцию?

Является ли плохой практикой всегда создавать транзакцию?

Например, хорошей практикой является создание транзакции только для одного простого SELECT?

Какова стоимость создания транзакции, когда она не нужна?

Даже если вы используете уровень изоляции, например READ UNCOMMITTED, это плохая практика?

71 голос | спросил elranu 28 Maypm13 2013, 19:43:27

3 ответа


88

Неправильная практика для создания транзакции всегда?

Это зависит от того, в каком контексте вы здесь говорите. Если это обновление, я настоятельно рекомендую использовать транзакции явно. Если это SELECT, то NO (явно).

Но подождите, что сначала нужно понять: Все в сервере sql содержится в транзакции.

Когда параметр сеанса IMPLICIT_TRANSACTIONS это OFF, и вы явно указываете begin tran и commit/rollback, тогда это обычно называют Явная транзакция . В противном случае вы получите транзакцию autocommit.

Когда IMPLICIT_TRANSACTIONS является ON a Неявная транзакция автоматически запускается при выполнении одного из типов операторов, задокументированных в онлайн-статье книг (например, SELECT /UPDATE /CREATE), и он должен быть зафиксирован или откат явно. Выполнение BEGIN TRAN в этом режиме будет увеличивать @@TRANCOUNT и запускать еще одну «вложенную» транзакцию)

Чтобы переключить режим, в котором вы находитесь, вы должны использовать

SET IMPLICIT_TRANSACTIONS ON

или

SET IMPLICIT_TRANSACTIONS OFF

select @@OPTIONS & 2

, если выше возвращает 2, вы находитесь в режиме неявной транзакции. Если он возвращает 0, вы находитесь в autocommit.

сколько стоит создание транзакции, когда это действительно не нужно?

Транзакции необходимы, чтобы перевести базу данных из одного согласованного состояния в другое согласованное состояние. Транзакции не требуют затрат, поскольку нет альтернативы транзакциям. См. Использование уровней изоляции на основе версии версии

Даже если вы используете уровень изоляции read_uncomitted. Это плохая практика? потому что у него не должно быть проблем с блокировкой.

Уровень изоляции READ_UNCOMMITED позволит использовать грязные чтения по определению, т.е. одна транзакция сможет увидеть незафиксированные изменения, сделанные другой транзакцией. Что делает этот уровень изоляции, он расслабляет над головой блокировки - способ получения блокировок для защиты параллелизма базы данных.

Вы можете использовать это на уровне соединения /запроса, чтобы он не влиял на другие запросы.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

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

EDIT:

Из любопытства я сделал несколько тестов, измеряющих влияние на T-log с помощью счетчиков Perfmon, таких как Log Bytes Flushed /Sec, Log Flush Waits /Sec (количество коммитов в секунду, которые ждут завершения записи в LOG), так как ниже графика:

введите описание изображения здесь

пример кода:

create table testTran (id int, Name varchar(8))
go

-- 19 sec
-- Autocommit transaction
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
---------------------------------------------------
-- 2 sec
-- Implicit transaction
SET IMPLICIT_TRANSACTIONS ON
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
COMMIT;
SET IMPLICIT_TRANSACTIONS OFF


----------------------------------------------------
-- 2 sec
-- Explicit transaction
declare @i int
set @i = 0
BEGIN TRAN
WHILE @i < 100000
Begin
INSERT INTO testTran values (1,'Kin Shah')
set @i = @i+1
End
COMMIT TRAN

транзакции Autocommit : (Отредактировано как выделено @TravisGan)

  • Вставка занимает 19 секунд.
  • Каждый Autocommit будет очищать буфер T-журнала до диска из-за автокомита (после выделения @TravisGan, и я пропустил это, чтобы упомянуть).
  • Процесс CHECKPOINT будет быстро завершаться, так как количество грязного буфера для журналов, которое необходимо очистить, будет меньше, поскольку он работает тихо.

IMPLICIT & Явная транзакция:

  • Вставка заняла 2 секунды.
  • Для транзакции EXPLICIT буферы журнала будут очищаться только после их заполнения.
  • В отличие от транзакции Autocommit, в транзакции EXPLICIT,Процесс CHECKPOINT займет больше времени, так как у него будет больше буферов журналов для очистки (помните, что буферы журналов очищаются только тогда, когда они заполнены).

Существует DMV sys.dm_tran_database_transactions , который будет возвращать информацию о транзакциях на уровне базы данных.

Очевидно, что это скорее упрощенная проверка, показывающая влияние. Другие факторы, такие как дисковая подсистема, параметры автоматического роста базы данных, начальный размер базы данных, другие процессы, запущенные на одном сервере \ база данных и т. Д., Также будут иметь влияние.

Из приведенных выше тестов не существует никакой разницы между Implicit & Явные транзакции.

Благодаря @TravisGan за помощь в добавлении ответа.

ответил Kin 28 Maypm13 2013, 20:10:36
33

Оператор SQL всегда работает в транзакции. Если вы не запустите его явно, каждый оператор SQL будет выполняться в транзакции сам по себе.

Единственный выбор - объединить ли несколько операторов в одну транзакцию. Транзакции, охватывающие несколько операторов, оставляют блокировки, которые вредят параллелизму. Поэтому «всегда» создание транзакций - это не очень хорошая идея. Вы должны балансировать стоимость с выгодой.

ответил Andomar 28 Maypm13 2013, 22:01:08
1

Проблема заключается в том, должна ли группа операций рассматриваться как одно действие. Другими словами, все операции должны быть завершены и успешно завершены или ни одна из операций не может быть выполнена. Если у вас есть сценарий, который требует, чтобы вы прочитали предварительные данные, а затем выполните обновления на основе этих данных, тогда первоначальное чтение должно быть частью транзакции. Примечание. Я стараюсь избегать выбора /вставки /обновления. Область транзакции может фактически находиться на уровне приложения и включать несколько операций с базами данных. Подумайте о классических шаблонах, таких как резервирование места в самолете или запрос или снятие банковского баланса. Необходимо рассмотреть более широкий взгляд на проблему, чтобы гарантировать, что все приложение дает надежные, согласованные данные.

ответил Ray 18 PMpMon, 18 Apr 2016 17:28:58 +030028Monday 2016, 17:28:58

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132