ロックの自然解除について調査中

このQ&Aのポイント
  • SQL Server 2008を使用している場合、SELECT~with(UPDLOCK)~などでレコードをロックした状態でクライアントプログラムが異常終了した場合に、ロックは自然に解除されるのか調査中です。
  • 検索の結果、Oracleではロックが残ってしまうが、MySQLやSQL Serverではそうでもないという印象がありますが、具体的な根拠が見つかっていません。
  • もしロックが自然に解除されない場合、対策を考える必要があるため、詳細な情報を求めています。
回答を見る
  • ベストアンサー

ロックの自然解除について

SQL Server 2008 を使用しています。 SELECT~with(UPDLOCK)~ などでレコードをロックした状態でクライアントプログラムが 異常終了した場合に、ロックが自然に解除されるかどうかについて調べているのですが、 ネットで検索しても答えは見つかりませんでした。 実験ではクライアント側のLANケーブルを抜けばロックが解除されたので、「自然に解除 される」が結論だとは思うのですが、文書のエビデンスが欲しいです。 検索の過程で得た印象では、「Oracleではロックが残ってしまうが、MySQLやSQL Serverでは そうでもない」という感じなのですが、  (1)Oracleではそうなる、という根拠  (2)SQL Serverではそうならない、という根拠  (3)またはその印象が間違っているという指摘 があったら教えてください。 よろしくお願いします。 自然に解除されないのであれば対策を作らなければならないので、調べています。

質問者が選んだベストアンサー

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.2

 SQL Serverのロック機構は、トランザクション境界内で実行されます。  http://technet.microsoft.com/ja-jp/library/ms186690%28SQL.90%29.aspx(2005の記事ですが、2008でも基本的に同じです。)    さて、トランザクション制御は、セッション制御と絡み合いますが、事故によりセッションが切断された場合は、トランザクションはロールバックされます。この処理は、  http://technet.microsoft.com/ja-jp/library/ms175523%28SQL.90%29.aspx(同じく2005の記事です。が、2008でも、基本的に同じです。)  に記述があります。  二つを合わせると、アプリケーションが落ちた場合やネットワークが切断された場合は、トランザクションがロールバックされることにより、ロックも解除されると解釈できますが、どうでしょうか?  実際、挙動もこれであっていると思います。

programmer38
質問者

お礼

ありがとうございます。 ネットワーク切断がロック解除につながる事の文書のエビデンスを得ることができました。 (ただしKeepAliveの設定が長いと解除までに時間がかかる事はある)

その他の回答 (1)

  • SaKaKashi
  • ベストアンサー率24% (755/3136)
回答No.1

クライアントプログラムとDBサーバの物理的関係に依存します。 DBサーバとクライアントプログラムの動作しているPCが同じなら、クライアントプログラムが異常終了したらすぐにロック解放される。 DBサーバとクライアントプログラムの動作しているPCがネットワーク接続で異なるPCの場合、クライアントプログラムが異常終了してもDBサーバ側での認識はかなり送れる場合がほとんどで、たいていは、 DBサーバ側の設定にクライアントプログラムとの死活監視時間が設定可能で、この死活監視時間が過ぎてもクライアントプログラムが応答しなければクライアントプログラムの異常終了を認識してロックが解除されます。 どのDBでもロックが解除されないと言うことはないはず。ですが、バグはありますけどね。

programmer38
質問者

お礼

死活監視→Keep Aliveだと思い検索したところ、SQL Serverの挙動についてはいろいろ出てきました。 TCP/IPの接続の監視を、SQL Serverの2000では2時間、2008では30秒でやっているようです。 ありがとうございます。

関連するQ&A

  • DBロックを待ち続ける方法

    ロックがかかったテーブルに対して、 SELECT文を発行する際、ロックが解除されるまで 待ち続けるヒント句のようなものは SQL SERVERに存在するのでしょうか? (Oracleの「SELECT~FOR UPDATE文」に相当するものは  存在しないのでしょうか?) 使用しているDBはSQL SERVER 2000 です。

  • ユーザアカウントのロックを解除出来ません

    こんにちは。 ある企業のIT担当者です。 一人のユーザのアカウントがロックされましたので、ADから解除をしました。 しかし10秒後、ロックされた状態になります。 何度繰り返しても同じ状況です。 どなたかアドバイスを頂きますと大変幸いです。 よろしくお願いします。 クライアントPC:Windows 7 Pro ドメインコントローラー: Windows Server 2008 R2 Standard

  • DBサーバーはどれがいいのですか?

    MySQL、PostgreSQL、SQLサーバー、ORACLEデータベースについて 仮に、ユーザが5000万人のSNSを作った場合、MySQLやPostgreSQLで対応できますか? 検索に時間がかかったりするのでしょうか? その場合、DBをORACLEにしたほうがいいのでしょうか? ■費用について もし、DBサーバーを1台設置して、ORACLEにした場合、初期費用や毎月のコストはどのくらいになるのでしょうか? ORACLE対応のDBサーバーの金額等も教えて頂ければ幸いです。 あと、SNSの会員が10万人までだとしたら、 MySQL、PostgreSQL、SQLサーバー、ORACLEのうちだと、どれがコスト的に一番効率的でしょうか?

  • 排他ロックしたレコードが、別トランザクションから参照されてしまい困っています。

    SQL Server2000を使用し、 あるトランザクションで排他ロック(XLOCK)をかけたレコードが 他のトランザクションから共有ロックを使用し参照できてしまう状態は存在するのでしょうか? 排他ロックをかけたレコードが 他のトランザクションから参照できてしまい困っています。 現在、下記の環境で開発を行っております。 ・サーバ側 Windows Server2003 SQL Server2000(sp4) ・クライアント側 Windows Xp(sp3) jdk6.0 jdbc 3.0 Type4 以下が具体的な状況となります。 前提として、 ・二つのトランザクション(以下A、Bと表記します)が存在する。 ・AとBは別のユーザでコネクションを張っている。 ・autoCommitはfalseに設定している。 ・テーブルにプライマリキーやインデックスは張っていない。 ・レコードは10件。 ・分離レベルはREAD COMMITED (1)Aから、「SELECT * FROM TEST_TABLE WITH(XLOCK) 」を発行 (2)Bから、「SELECT * FROM TEST_TABLE」を発行 このような状況で、(1)、(2)の順で処理を行った場合に 私の認識では、(2)の検索時にタイムアウト等が発生するという認識です。 しかし、(2)のSQLは正常に終了し、(1)と同じデータが取得されてしまいます。 ◆その他、確認したこと ・(1)の処理直後に処理を停止し、Enterprise Managerでロックが取得されているか確認したところ、トランザクションAがすべてのレコードを排他ロック(X)していた。 ・(2)の処理直後にロックの状態を確認しても、やはりトランザクションAが、排他ロック(X)していた。 ・CSEを使いODBC経由で同様の操作を行った場合も同じ動作がおこる。 ・(1)WITH(XLOCK, TABLOCK)とすると(2)でデータが取得できなくなる。 ・(2)のSQLを「SELECT * FROM TEST_TABLE WHERE COLUMN01 > 0」のように指定するとタイムアウトする(期待通りの動き) ・(2)のSQLを「SELECT COLUMN01 FROM TEST_TABLE WHERE COLUMN01 > 0」のように指定すると、今度は、なぜか取得出来てしまう。 ・(1)と(2)の間にトランザクションAでUPDATEなどを行うと(COMMITはしない)(2)のSQLのWHERE句や取得するカラムに関係なく、(2)のSQLはタイムアウトする(当り前か。。。) いろいろ書きましたが、排他ロックされたレコードに 共有ロックはかけれないという認識なのですが、 そうではないのでしょうか? また、そうではない場合どういった場合に、 共有ロックが可能となるのでしょうか? SQL Serverの排他制御に詳しい方や 同じような現象に陥った方がいましたら、ご教授お願いします。

  • PHPでMySQLテーブルロック一覧取得

    PHPでMySQLテーブルロックされている一覧を取得したいですがどのようにすれば良いかご教授願います。 Web検索で調べるとロック状態はmysql_list_processesや、show processlistでも試してみましたが、思うような結果は得られませんでした。正常には動作していますが、欲しいデータが取り出せないですす。。。 単純に、現在ロックしているテーブル名(レコードロックは不要です。)を一覧で出力させることはできないのでしょうか? PHPから実施できるやり方をご教授頂けると幸いです。 -------Test Program()--------- <?php $link = mysql_connect('localhost', 'login_id', 'login_pass'); mysql_select_db('db_name'); mysql_query('LOCK TABLES table1 WRITE'); mysql_query('INSERT INTO table1 SET field1 = "test", field2 = "1"'); //$result = mysql_list_processes($link); 以下のSQL文とも入れ替えて試しました。 $result = mysql_query('show processlist'); while ($row = mysql_fetch_assoc($result)){ printf("%s %s %s %s %s %s %s %s\n", $row["Id"], $row["User"], $row["Host"], $row["db"], $row["Command"], $row["Time"] , $row["State"], $row["Info"]); } mysql_free_result($result); mysql_query('UNLOCK TABLES'); ?>

    • ベストアンサー
    • MySQL
  • ドメインに所属しているPCのロック時間

    サーバはWindows Server 2003,クライアントはWindows XP,Windows 2000合わせて80台ほどあります。単一のADドメインを組んで、すべてのクライアントはドメイン配下のネットワーク内からアクセスします。 会社の方針で、電力削減と余剰PC削減のためPCの使用率を調査しろという命令が出たのですが、「スクリーンセーバでロックをかけて、ロックを解除するまでの間の時間の統計を取るように」という内容でした。 「コンピュータの管理」コンソール内の「セッション」で見ると共有フォルダ(あるいはSQLサーバなど)にアクセスしているPCの接続時間・アイドル時間などを見ることは可能ですが、上記のような条件を満たすようなことが、Windows Server 2003の標準的な機能を使ってできるのか返答に困っています。 可能だとすると、「監査ポリシー」を新たに作成してやるのが一番手っ取り早いのかなと考えますが、あまり良い智恵が思い浮かびません。 可能であれば御教授下さい。よろしくお願いします。

  • 違いを教えてください。

    全く基本的なことで恐縮ですが、 以下の4つの違いを教えてください。 SQL Server Oracle PostgresSQL MySQL よろしくお願いします。

  • Oracle 10g以降 ユーザーインターフェース

    質問いたします。 Oracle 10gの正規版(やすいもの)を買って Oracleを使用するつもりなのですが、 (1)グラフィカルユーザーインターフェース SQL Server 2000やAccessのような、SQL(SQLServerではSelect文) をGUIで作成できる機能はOracle10g以降では提供されているのでしょか? (会社ではOracleのDBは扱ったことはありますが、Accessからの リンクテーブルやVB.Netからのアクセスが主、直接は操作していません)あるいは、GUIインターフェースで操作できるものは Oracleではオプションで買うことになるのでしょうか? (2)日本語名 SQL Server 2000やAccessでは日本語名称が使用できますが、 MySQLやPostgresは英文字(日本語で作ったことがない)しかし要したことがありません。 Oracle 10g以降では日本語名称は使用できるでしょうか? ※おそらく、Unicodeかなんかの関係でタブーではあると思いますが。 よろしくお願いします。

  • DBサーバと接続しているプロセスを見たい

    Oracleクライアントから、他のどのプロセス(もしくはスレッドか、 コネクションか)がサーバと接続しているかを見たいですが、 クライアントからは可能でしょうか?SQLで実現できますか? ご教授お願いいたします。

  • select for updateのロック

    オラクルのselect for updateでロックをするタイミングがいつですか? こんなPL/SQLのコードがあったとします。 ---↓↓↓ソースコードここから↓↓↓------------------------- select * from テーブル1 where id = 1 for update; ・・・・・(a) ~ update テーブル1 set kingaku=100 where id = 1 ・・・・・(b) ~ commit; ---↑↑↑ソースコードここまで↑↑↑------------------------- id = 1のレコードがロックされるのは(a)、(b)どちらのタイミングですか? また、このロックは ・他トランザクションから読めるけど更新できない ・他トランザクションからは読むことすらできない のどちらでしょうか? よろしくお願いします。