BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース NOLOCKをLINQ to SQLおよびLINQ to Entitiesで実装

NOLOCKをLINQ to SQLおよびLINQ to Entitiesで実装

ブックマーク

近ごろScott Hanselman氏は、 LINQ to SQLおよびLINQ to Entitiesを使用する際のヒントを取り上げた、非常に役立つ記事(ブログ・英語)をブログ上に掲載した。問題は、SQLデベロッパが慣れているように、LINQクエ リで生成されたSQLを獲得し、NOLOCKヒントを使用する方法である。

LINQ to SQLはSQLクエリを動的に作成するので、クエリの外観に影響を与えることは重要なことである。Scott氏は、すべてにおいてNOLOCKを使用するのではなく、NOLOCKは最終手段として使用すべきだと指摘している。

しかしながら、NOLOCKを使用すること(「誰もが」それをどこかの時点で使用したことがあるけれども)は、一般的に最終手段だと考えられている。NOLOCKを使用するクエリは、正しい結果を返すことを保証されていない。技術的には、まったく返さない。

SQL 2005は、スナップショットベースの分離レベル(source)があり、ダーティー読み取りを許可せずに、リーダーをブロックしているライターから阻止したり、またその逆にライターをブロックしているリーダーから阻止したりする。

過去にNOLOCKがかなり大きいシステムで非常によく機能したと言ったが、 NOLOCKを拒む人がいるのを耳にする。確かにそれは個人の「正しい結果」に対する定義に因る。

Scott氏は、NOLOCKヒントを追加するタスクを遂行する以下の3つの方法を挙げた。

推奨される方法は、LINQ to SQLまたは LINQ to Entitiesのどちらか一方で生成されたコマンドのトランザクションオプションに影響を与える方法としてTransactionScopeを使用することである。

LINQ to SQLは、コンテキストでのトランザクションの設定を明確にサポートするので、コンテキストからその関係が分かり、開いたり、トランザクションを開始した り、コンテキストで設定したりできる。これはSQL 2005がトランザクションを推進しすぎているときに望ましい とされるが、推奨されるメソッドはTransactionScopeである。

ProductsNewViewData viewData = new ProductsNewViewData();
using (var t = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions {
IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
}))
{
viewData.Suppliers = northwind.Suppliers.ToList();
viewData.Categories = northwind.Categories.ToList();
}

2つ目の方法は、試行された真のストアードプロシージャーである。

2つ目の方法は、 クエリが読み出し元のテーブルをロックダウンする必要がないならば、未だにLINQ to SQLからStored Procedures(sprocs)を作成したり呼び出すことが可能であり、これらのsprocsにはNOLOCKが含まれる可能性があり、TransactionScopeはLINQ to SQLまたはLINQ to Entity生成のSQLにとってより良い選択である。

3つ目の方法は、以下のようにDataContextレベルでそれを設定することである。

それをDataContextレベルで設定するという3つ目の方法は、(そのコンテキストで実行されたすべての生成済みLINQ to SQLクエリに明らかに影響を与えるが)、 以下のコマンドを実行することである。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED (source)

Scott氏によるそれぞれの手法には確かに賛否両論ある。そもそもNOLOCKを使用することについて、またデプロイメントを考慮したときに NOLOCKはどこで存続すべきかについての議論もある。たとえば、NOLOCK設定が推奨される方法でおこなわれ(オプション1)、NOLOCKがもはや不必要となったとき、完全なバイナリデプロイメントが必要となる。しかし、NOLOCKがストアードプロシージャーメソッドで使用される場合、唯一の変更はデータベースレベルでおこなわれる。

もちろんNOLOCKは、こんにちSQLで使用されている数多くのヒントの1つに過ぎず、他のヒントが同様に使用できない理由はどこにもない。

LINQ to SQLやLINQ to Entitiesの詳細については、MSDNのWebサイト(source)を参照。Scott Hanselman氏については、自身がブログを書いているComputerzen.com(ブログ・英語)で参照できる。

 原文はこちらです:http://www.infoq.com/news/2008/03/linq-nolock

この記事に星をつける

おすすめ度
スタイル

BT