Плохая практика всегда создавать транзакцию?
Это зависит от того, в каком контексте вы говорите здесь. Если это обновление, я настоятельно рекомендую явно использовать TRANSACTIONS. Если это SELECT, то НЕТ (явно).
Но подождите, чтобы понять больше: сначала все, что есть на сервере sql, содержится в транзакции.
Когда параметр сеанса IMPLICIT_TRANSACTIONS
установлен, OFF
и вы явно указываете, begin tran
а commit/rollback
затем это обычно называют явной транзакцией . В противном случае вы получите транзакцию автоматического подтверждения.
Когда IMPLICIT_TRANSACTIONS
это неявная транзакция автоматически запускается при выполнении одного из типов операторов , зарегистрированных в книгах онлайн статье (например , / / ) , и оно должно быть совершенно или отката в явном виде. Выполнение в этом режиме увеличило бы и запустило еще одну «вложенную» транзакцию)ON
SELECT
UPDATE
CREATE
BEGIN TRAN
@@TRANCOUNT
Чтобы переключиться в какой режим вы используете, вы должны использовать
SET IMPLICIT_TRANSACTIONS ON
или же
SET IMPLICIT_TRANSACTIONS OFF
select @@OPTIONS & 2
если выше возвращает 2, вы находитесь в неявном режиме транзакции. Если он возвращает 0, вы находитесь в автокоммите.
сколько стоит создание транзакции, когда это действительно не нужно?
Транзакции необходимы для перевода базы данных из одного согласованного состояния в другое согласованное состояние. Транзакции не имеют стоимости, так как нет альтернативы транзакциям. См. Использование уровней изоляции на основе управления версиями строк.
Даже если вы используете уровень изоляции read_uncomited. Это плохая практика? потому что у него не должно быть проблем с блокировкой.
Уровень изоляции READ_UNCOMMITED допускает грязное чтение по определению, т. Е. Одна транзакция сможет увидеть незавершенные изменения, внесенные другой транзакцией. Что делает этот уровень изоляции, так это ослабляет накладные расходы - метод получения блокировок для защиты параллелизма базы данных.
Вы можете использовать это на уровне соединения / запроса, чтобы это не влияло на другие запросы.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Нашел интересную статью Джеффа Этвуда, описывающую тупики из-за «Обедающей философской головоломки» и описывающую уровень изоляции зафиксированных моментальных снимков .
РЕДАКТИРОВАТЬ:
Из любопытства я провел некоторый тест, измеряющий влияние на T-log с помощью счетчиков Perfmon, таких как Log Fteshed / 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
Автокоммит транзакций : (отредактировано, как выделено @TravisGan)
- Вставка заняла 19 секунд.
- Каждый Autocommit будет сбрасывать буфер T-log на диск из-за autocomit (после выделения @TravisGan, и я пропустил это, чтобы упомянуть).
- Процесс CHECKPOINT будет завершаться быстро, так как объем грязного буфера журнала, который требуется очистить, будет меньше, так как он часто работает тихо.
ПОДТВЕРЖДАЮТ & Явная Сделка:
- Вставка заняла 2 сек.
- Для транзакции EXPLICIT буферы журнала будут сбрасываться только тогда, когда они заполнены.
- В отличие от транзакции Autocommit, в транзакции EXPLICIT процесс CHECKPOINT будет длиться дольше, так как он будет иметь больше буферов журнала для очистки (помните, что буферы журнала сбрасываются, только когда они заполнены).
Существует DMV sys.dm_tran_database_transactions, которая будет возвращать информацию о транзакциях на уровне базы данных.
Очевидно, это скорее своего рода упрощенный тест, чтобы показать влияние. Другие факторы, такие как дисковая подсистема, параметры автоматического увеличения базы данных, начальный размер базы данных, другие процессы, выполняющиеся на том же сервере \ базе данных, и т. Д. Также будут влиять.
Из приведенных выше тестов практически не существует различий между неявными и явными транзакциями.
Спасибо @TravisGan за помощь, чтобы добавить больше к ответу.
BEGIN TRAN SELECT ... COMMIT
против толькоSELECT
что, кажется, очень незначительная разница в производительности.