none
NOLOCKヒントを使わないダーティーリードの強制について RRS feed

  • 質問


  • お世話になっております。

    現在、使用中のSQL2005からユーザーAがデータを参照しています。
    この参照におけるロックを避けるため、ユーザーAからの参照は
    すべてダーティーリードで行うようにする予定ですが
    クエリにNOLOCKヒントを付ける以外にこれを可能にする方法が無いか、
    現在調査中です。

    例えば、ログイン「ユーザーA」からのデータ参照は常にダーティーリードを
    強制させるようサーバー側で設定することは出来ないのでしょうか?

    サーバー側で対応可能な他の解決策でも構いませんので
    情報をお持ちの方がいらっしゃいましたらご教授願えますでしょうか?

    もしNOLOCKヒントつける以外に方法が無い場合はその旨
    助言頂きたく、よろしくお願い致します。
    (その場合は速やかにあきらめます)

    どうぞよろしくお願い致します。

    2014年6月5日 2:15

回答

  • ダーティリードで本当に問題ないですか?

    READ_COMMITTED_SNAPSHOTを使うというのも手かと思います。
    http://technet.microsoft.com/ja-jp/sqlserver/gg639075#EJC

    まあいずれにしてもユーザAに強制、とはなりませんが、デフォルトでの読み取り操作でロックを回避することはできます。

    • 回答としてマーク 星 睦美 2014年6月9日 3:01
    2014年6月5日 2:20
  • >ストアドを使えばコントロール可能ということですね。
    ただ、現在使用中のクエリをすべてストアドに置き換えるのは難しいかもしれません。。

    すみません。私の書き方が悪かったですね。ストアドでなくても、以下のようにSqlConnectionで分離レベルを指定できますので、ユーザー毎にここを制御すれば実現できるのではないかと思います。

    SqlConnection.BeginTransaction メソッド (IsolationLevel)
    http://msdn.microsoft.com/ja-jp/library/5ha4240h(v=vs.110).aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク 星 睦美 2014年6月9日 3:01
    2014年6月5日 4:34

すべての返信

  • ダーティリードで本当に問題ないですか?

    READ_COMMITTED_SNAPSHOTを使うというのも手かと思います。
    http://technet.microsoft.com/ja-jp/sqlserver/gg639075#EJC

    まあいずれにしてもユーザAに強制、とはなりませんが、デフォルトでの読み取り操作でロックを回避することはできます。

    • 回答としてマーク 星 睦美 2014年6月9日 3:01
    2014年6月5日 2:20
  • 分離レベルをREAD UNCOMMITTEDにすればダーティーリード可能です。ログインユーザー毎に制御する機能は無いように思いますが、ストアドプロシージャでログインユーザーを判断し、分離レベルを決定すればいけるんじゃないかと思います。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2014年6月5日 2:33
  • なちゃ様

    早速情報を頂きありがとうございます。

    やりたいことはダーティーリードで問題ございません。

    「READ_COMMITTED_SNAPSHOT」について拝見致しましたが
    データベースに対して行う設定とのことですので
    これであればサーバー側でコントロールできそうです。

    ただ、更新頻度によってはtempdbが肥大化することがあるとのことで
    現在の更新頻度を確認したいと思います。

    同サーバー上の他のDBアクセスへの影響も考慮しつつ
    検討させて頂きます。

    ありがとうございました。

    2014年6月5日 3:02
  • trapemiya様

    早速情報を頂きありがとうございます。

    ストアドを使えばコントロール可能ということですね。
    ただ、現在使用中のクエリをすべてストアドに置き換えるのは難しいかもしれません。。

    ログインユーザー毎に制御する機能はなさそう
    ということで了解しました。


    ありがとうございました。
    2014年6月5日 3:03
  • >ストアドを使えばコントロール可能ということですね。
    ただ、現在使用中のクエリをすべてストアドに置き換えるのは難しいかもしれません。。

    すみません。私の書き方が悪かったですね。ストアドでなくても、以下のようにSqlConnectionで分離レベルを指定できますので、ユーザー毎にここを制御すれば実現できるのではないかと思います。

    SqlConnection.BeginTransaction メソッド (IsolationLevel)
    http://msdn.microsoft.com/ja-jp/library/5ha4240h(v=vs.110).aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク 星 睦美 2014年6月9日 3:01
    2014年6月5日 4:34
  • trapemiya様

    追加情報ありがとうございます。

    私自身、あまり詳しくなくて恐縮ですが
    このメソッドはクライアント側のアプリケーションで指定するものですよね?

    今回、クライアント側のアプリには手を入れずサーバー側だけで出来る手法が無いかと調査しておりましたが
    やはりアプリ改修無しでは難しいということでしょうか。。。


    以上
    どうぞよろしくお願い致します。
    2014年6月6日 5:34
  • なちゃ様

    お世話になっております。

    ご教授頂いた「READ_COMMITTED_SNAPSHOT」について
    追加で教えて頂きたいのですが、
    例えば

    DB1←(ビューで参照)DB2←(ビューからSELECT)アプリ

    のようにビューを中継してデータを参照する場合
    「READ_COMMITTED_SNAPSHOT」は実態のあるDB1に対して
    有効にするという認識で間違いございませんでしょうか?


    どうぞよろしくお願い致します。
    2014年6月6日 6:02
  • >このメソッドはクライアント側のアプリケーションで指定するものですよね?

    その通りです。

    >今回、クライアント側のアプリには手を入れずサーバー側だけで出来る手法が無いかと調査しておりましたが
    やはりアプリ改修無しでは難しいということでしょうか。。。

    アプリケーションでSQL文を発行して読んでいるんでしたよね。そこを改修しないとなると、SQL Server自体の機能に頼ることになると思いますが、前にも書いた通り、SQL Serverがログインユーザーもしくはデータベースユーザーで判断して、分離レベルを変更したり、ロックヒントを変更したりするような機能は、普通に考えて無いと思います。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2014年6月6日 7:34
  • trapemiya様

    返信頂きありがとうございます。

    やはりアプリ側で手を入れるのがベストということですよね。。

    最後に
    なちゃ様に提案頂いた「READ_COMMITTED_SNAPSHOT」が使えるかどうか検討してみたいと思います。
    それで駄目なら諦めてアプリ側での対応を打診します。

    何度もありがとうございました。
    2014年6月6日 9:03