2016-10-12 21 views
2

official example hereには、明示的に定義されたトランザクションと共にSET TRANSACTION ISOLATION LEVELが使用されています。SET TRANSACTION ISOLATION LEVELはトランザクションでのみ機能しますか?

私の質問は、私はのように、SqlCommandオブジェクトからクエリを実行すると、次のとおりです。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
SELECT * from MyTable 

私が設定した新しい分離レベルの恩恵を受けるだろうか?

または、このようなトランザクションを明示的に定義する必要はありますか?

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
BEGIN TRANSACTION; 
    SELECT * from MyTable 
COMMIT TRANSACTION; 

UPDATE: Randy Levy's answerを1として、次のように、私は私のクエリを更新します。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
SELECT * from MyTable; 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 

これはpossible isolation level leaks when using poolingを克服することです。

+1

あなたはトランザクションを必要はありません。私が間違っていない限り、 'READ UNCOMMITTED'は' NOLOCK'ヒントを使用しているかのように_any_ select文を動作させます。 – ZLK

答えて

2

はい、明示的なBEGIN TRANSACTIONに含まれていなくても設定したトランザクション分離レベルのメリットがあります。トランザクション分離レベルを設定すると、接続レベルで設定されます。 SET TRANSACTION ISOLATION LEVEL (Transact-SQL)から

:分離レベルのオプションの

つだけを一度に設定することができ、それが明示的に変更されるまで、それが は、その接続用に設定されたまま。

発生する可能性のある「問題」は、プーリングを使用するときに異なる接続間で分離レベルがリークする可能性があることです。明示的に分離レベルをコードの特定の部分(またはいくつかの部分)に設定している場合(デフォルトのほとんどの場所を使用)、接続プーリングを使用している場合。これは、コードがデフォルトの分離レベル "A"を期待しているが、分離レベルが明示的に "B"に設定されている接続を取得すると、奇妙な問題を引き起こす可能性があります。

この問題は、現在のSQL Serverのそれ以降のバージョンで修正されているようだ:SQL Server: Isolation level leaks across pooled connections

+0

優れたキャッチ、それを指摘してくれてありがとう! [デフォルトの分離レベルはREAD COMMITTED](http://stackoverflow.com/questions/10003026/what-is-the-default-transaction-isolation-level-for-sql-server-with-ado-net)ですので、 、 私のクエリを次のように更新することは意味があると思います: 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT * from MyTable; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 私はこの可能性のあるバグによって保護されるべきです、なぜなら私はSQL Server 2005+ – Adi

1

最初の1

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
SELECT * from MyTable 

は動作します。設定したトランザクション・レベルは、後続の各トランザクションに適用され、SELECT文はそれ自身の暗黙のトランザクションです。

トランザクションを明示的に開始する必要があるのは、複数の読み込みで一定の整合性を確保する必要がある場合だけです。たとえば、SERIALIZABLEを使用すると、トランザクション内で複数のSELECTをラップして、基礎となるデータが読まれている間は変更されないようにすることができます。

+0

マルチステートメント整合性が必要な場合は、REPEATABLE_READおよびSNAPSHOTレベルで明示的なトランザクションを追加するだけです。 –

+0

はい - 私は例としてSERIALIZABLEを使用していることを明確にすべきでした。 –

1

SQL Serverのすべてのステートメントは、トランザクションのコンテキストで実行されます。あなたは

select * from [dbo].[foobar]; 

SQL Serverのような何かをするときは本当にありません:だから

begin transaction; 
select * from [dbo].[foobar]; 
commit; 

、トランザクションを影響しない、明示的なトランザクション分離レベルを設定します。あなたのためにデータベースエンジンが起動する暗黙のものさえ!

関連する問題