回答:
トランザクションを常に作成するのは悪い習慣ですか?
ここで話しているコンテキストによって異なります。更新の場合、TRANSACTIONSを明示的に使用することを強くお勧めします。SELECTの場合、NO(明示的に)。
しかし、最初に理解する必要があることを待ってください。SQLサーバーのすべてがトランザクションに含まれています。
セッションオプションIMPLICIT_TRANSACTIONS
がOFF
あり、明示的に指定begin tran
したcommit/rollback
場合、これは一般にExplicit Transactionとして知られています。それ以外の場合は、自動コミットトランザクションを取得します。
ときに IMPLICIT_TRANSACTIONS
された暗黙のトランザクションは、オンラインブックの記事(例えばに記載の種類の文を実行したときに自動的に起動される/ / )、それがコミットまたは明示的にロールバックする必要があります。このモードでを実行すると、別の「ネストされた」トランザクションが増加して開始されます)ON
SELECT
UPDATE
CREATE
BEGIN TRAN
@@TRANCOUNT
現在のモードを切り替えるには、次を使用します
SET IMPLICIT_TRANSACTIONS ON
または
SET IMPLICIT_TRANSACTIONS OFF
select @@OPTIONS & 2
上記が2を返す場合、暗黙のトランザクションモードになっています。0が返された場合、自動コミットされています。
トランザクションが本当に必要でない場合、トランザクションを作成するコストはいくらですか?
データベースをある一貫性のある状態から別の一貫性のある状態にするには、トランザクションが必要です。トランザクションに代わるものがないため、トランザクションにはコストがかかりません。参照:行バージョン管理ベースの分離レベルの使用
分離レベルread_uncomittedを使用している場合でも。悪い習慣ですか?ロックに問題はないはずだからです。
READ_UNCOMMITED分離レベルは、定義によりダーティリードを許可します。つまり、1つのトランザクションは、他のトランザクションによって行われたコミットされていない変更を見ることができます。この分離レベルが行うことは、ロックのオーバーヘッドを緩和することです。ロックを取得してデータベースの同時実行性を保護する方法です。
これを接続/クエリレベルで使用して、他のクエリに影響を与えないようにすることができます。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
食事哲学者パズルによるデッドロックと読み取りコミットスナップショット分離レベルについて説明するジェフアトウッドによる 興味深い記事を見つけました。
好奇心から、以下のグラフのように、Log Bytes Flushed / Sec、Log Flush Waits / Sec(ログフラッシュの発生を待機している1秒あたりのコミット数)などのPerfmonカウンターでTログへの影響を測定するテストを行いました。
サンプルコード:
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で強調表示されているように編集)
暗黙的および明示的なトランザクション:
データベースレベルでトランザクションに関する情報を返すDMV sys.dm_tran_database_transactionsがあります。
明らかに、これは影響を示すためのより単純なテストです。ディスクサブシステム、データベースの自動拡張設定、データベースの初期サイズ、同じサーバー\データベースで実行されている他のプロセスなど、他の要因も影響します。
上記のテストから、暗黙的トランザクションと明示的トランザクションの違いはほとんどありません。
@TravisGanが回答をさらに追加してくれたことに感謝します。
問題は、操作のグループを単一のアクションとして扱う必要があるかどうかです。つまり、すべての操作を正常に完了してコミットする必要があります。そうでない場合、操作をコミットできません。予備データを読み取り、そのデータに基づいて更新を実行する必要があるシナリオがある場合、最初の読み取りはおそらくトランザクションの一部である必要があります。注:意図的に選択/挿入/更新を避けています。トランザクションスコープは、実際にはアプリケーションレベルであり、複数のデータベース操作が含まれる場合があります。飛行機の座席予約や銀行残高照会/引き出しなどの古典的なパターンを考えてください。アプリケーション全体から信頼性の高い一貫性のあるデータが得られるようにするには、問題をより広く理解する必要があります。
BEGIN TRAN SELECT ... COMMIT
vsの影響を見るSELECT
と、パフォーマンスにごくわずかな違いがあるように見えます。