none
デバッグ時にコネクションオブジェクトをOpenする前に停止ボタンを押してもSQLにデータが書き込まれてしまう。 RRS feed

  • 質問

  •  みなさん、こんにちは。
    VS2008 ProfessionalでWEBアプリケーションを作成しています。(Asp.Net2.0を使用)
    SQLデータベースに書き込みを行うロジックを作成しています。デバッグ時に、ブレークポイントを挿入してステップ実行しています。SqlConnectionオブジェクトのOpenメソッドをコールする前に停止ボタンを押してデバッグを終了しているのですが、SQL Server2005 Expressのデータベースにデータが書き込まれてしまいます。

     

     このような場合、以前はそんなことはなく書き込みが行われなかったと思うのですが、それは勘違いでこれが仕様なのでしょうか?
    一応うろ覚えの自分の記憶を信じてVS2008の修復インストールも実行したのですが、もう一度試してみると結果は同じで書き込まれてしまいます。

     

    #デバッグ時に使用しているブラウザはIE7です。

     

     仕様か仕様ではないかを含めてどのようにしたらこの問題を解決できるでしょうか?

     

    宜しくお願いします。

    2008年12月5日 11:35

回答

  • 自分の環境でも、Open よりずっと手前みブレークポイントを設定して実行を
    止めたつもりが、DB が更新されてしまうことはあります。

     

    ちなみに自分の環境は以下の通りです。

     

    Vista SP1 + .NET 3.5 SP1 + VS2008 Pro SP1 + SQL Server 2008 Exp

     

    仕様かどうかは分かりませんが、えいきちさんの勘違いではなく、IDE が壊れ
    ているわけでもないと思います。

    2008年12月5日 16:27
  •  
    こちらに書いておきましたが、Visual Studio では(開発効率をあげるために、)そのような挙動をするようになっています。
    どうしても、強制中断する機能が必要な場合は、Professinal 版とのことですので、ネイティブデバッグを有効にして運用するという手段があります。
     
    2008年12月8日 16:08

すべての返信

  • はじめまして。だどさんと申します。

     

    データベースの Open 前に終了して書き込みが終わっているということは、通常は起きないと思います・・・。

     

    余計な部分は全部削って、最も単純なスクリプトで再現可能かどうか試してみると良いと思います。そして、その現象が発生する最小のスクリプトを見ると何かわかるのではないでしょうか。

     

    ご参考になれば幸いです。

     

    -----------------------------------

    だどさん http://keicode.com/

     

    2008年12月5日 12:37
  •  

     -だどさん-さん、返信を下さりありがとうございます。
    このような場合では書き込みをしないはずだと思いつつも、”あれ、もしかしたら勘違いだったかも”と心が揺れ動いていたところでしたので-だどさん-さんからのアドバイスは非常に役に立ちました。ありがとうございました。

    早速、貴重なアドバイスに従ってコードを最小にしてみました。

    最小のスクリプトにしたものを下に掲載します。
    protected void btnSubmit_Click(object sender, EventArgs e){
      strA = "";
      strB = "";
      strC = "";
      strD = "test:" + DateTime.Now.ToString() ;//①<=ここにブレークポイント
     
      SqlConnection conn = new SqlConnection(strMySqlConnectionString);
      SqlCommand sqlCommandForWrite = new SqlCommand(strSqlStatement, conn);

      using (conn)
      {
          conn.Open();
          sqlCommandForWrite.ExecuteNonQuery();
      }
    }

    ①でブレークした後、他に何もせず停止ボタンを押してデバッグを終了してもデータベースに書き込まれてしまいます。
    サーバー エクスプローラーでデータベースを削除して再び”接続の追加”で接続を追加したりもしてみたのですが、依然この現象が発生します。

    ここから分かることはIDEが壊れたかな?といったことなんですが、どうやったら修復できるのかとんと見当がつきません。

    みなさん、宜しくお願いします。

    2008年12月5日 14:26
  • 自分の環境でも、Open よりずっと手前みブレークポイントを設定して実行を
    止めたつもりが、DB が更新されてしまうことはあります。

     

    ちなみに自分の環境は以下の通りです。

     

    Vista SP1 + .NET 3.5 SP1 + VS2008 Pro SP1 + SQL Server 2008 Exp

     

    仕様かどうかは分かりませんが、えいきちさんの勘違いではなく、IDE が壊れ
    ているわけでもないと思います。

    2008年12月5日 16:27
  • ご提示の環境の使用経験はありません。
    Visual Studio 2005では、その現象はまだ見かけたことはありません。

    通常は考えにくい現象ですね。
    本当にそうなるのでしたらIDEのバグと思います。

    その結論を出す前に、いろいろ疑ってみるべきと思います。
    ブレイクした時点では、DBへの接続はどうなっていますか?
    DBサーバーにてコネクション状態を確認してみて下さい。
    この確認は、IISとDBサーバーを再起動してDBへの接続をクリアし、
    DBサーバーにてコネクションがないのを確認してから行うとよりよいと思います。

    他に、ブレイクポイント到達前に同じ処理があって、
    それがたまたま実行されていたりしていませんか?

    別のアプローチとしては、そのSQLが更新するデータをあらかじめロックし、
    その状態で試す方法があります。
    更新がブロックされるため、そこから原因を特定できるかもしれません。

    2008年12月5日 19:19
  •  

     あとSQL Server プロファイラ([スタート]メニューから[SQL Server]→[パフォーマンスツール]にあります)を使って、SQL Serverにコマンドが送られているか確認してみるのもいいと思います。

     

     プログラムを修正するとブレークポイントの位置がずれたりするので、IDEのバグ(仕様?)かと思いますが、一度ブレークポイントを解除して、再度ブレークポイントを設定してみたてはどうでしょうか?

     

    2008年12月6日 1:06
  • CatTailさん、みなさん、こんにちは。
    CatTailさん、返信を下さりありがとうございます。

     

     VS2008をインストールした時に一緒にインストールされたのでSQL Server 2005 Express Editionがインストールされたと思っていたのですが、プログラムのアンインストールと変更で調べたところ”SQL Server 2005”としか記載されていませんでした。

     

     それで、スタートメニュー-[SQL Server 2005]には構成ツールフォルダしかなく、その中には”SQL Server構成マネージャ”、”SQL Server セキュリティ構成","SQL Server エラーと使用状況レポート"しかありませんでした。

     

    一体、このSQL Server 2005とはどのエディションなのでしょうか。
    他の方への返信を書いているうちにSQL Server 2005 ExpressEditionを使用しているという前提が覆ってしまったように思ったため最初にCatTailさんに返信させていただきます。

     

     それから、ブレークポイントですが、解除してもう一度設定しても書き込まれてしまいます。その他、解除してから①の場所のすぐ上に設定してみたのですがこれでも書き込まれてしまいました。

     

    2008年12月6日 2:46
  •  SurferOnWwwさん、皆さん、こんにちは。
    SurferOnWwwさん、返信を下さりありがとうございます。

     

    自分の環境ですが下のようになります。
    Vista SP1 + .NET 3.5 + VS2008 Pro + VS2008をインストールした時にインストールされたSQL Server 2005

     

    #SQL Server 2005 Express Editionを使用している前提でしたが、それがかなり疑わ
    #しくなっているので上記のように書かせていただきました。詳しくはCatTailさんへ
    #の返信をお読みください。

     

     書き込みが行われるのは、IDEが壊れているわけではないのでしょうか。。。

    もう少し皆さんの意見を聞かないと判断できなくなっています。

    2008年12月6日 3:02
  •  えいきち さんからの引用

    自分の環境ですが下のようになります。
    Vista SP1 + .NET 3.5 + VS2008 Pro + VS2008をインストールした時にインストールされたSQL Server 2005

     

    #SQL Server 2005 Express Editionを使用している前提でしたが、それがかなり疑わ
    #しくなっているので上記のように書かせていただきました。詳しくはCatTailさんへ
    #の返信をお読みください。

     

     書き込みが行われるのは、IDEが壊れているわけではないのでしょうか。。。

    もう少し皆さんの意見を聞かないと判断できなくなっています。

     

    「プログラムのアンインストールと変更」には "Express" とは表示されません
    が、Express もインストールされていると思います。

     

    接続文字列で Express か否かを確認できます。接続文字列は、Web.config

    の connectionStrings 要素か、Visual Studio のサーバーエクスプローラで該

    当する mdf を選択して、そのプロパティで確認できます。

     

    接続文字列が Data Source=.\SQLEXPRESS; ... User Instance=True と

    なっていれば Express です。

     

    #ブレークポイントを通り抜けてしまうというのは、確かにあってはいけない
     ことだと自分も思います。もう少し調べて何か分かったらまたここに書き込
     みます。

     

    2008年12月6日 4:20
  •  SurferOnWww さんからの引用

    #ブレークポイントを通り抜けてしまうというのは、確かにあってはいけない
     ことだと自分も思います。もう少し調べて何か分かったらまたここに書き込
     みます。

     

    以下の環境の別の PC でも試してみましたが、ブレークポイントを通り抜けてしまう
    というのは同じでした。

     

    Vista SP1 + .NET 3.5 SP1 + VWD2005 Exp + SQL Server 2005 Exp


    というわけで、IDE が壊れているということはないと思います。これが仕様というの
    はどうかと思いますので、やはりバグ相当の不具合のような気がします。

     

    ご参考に試したコードをアップしておきます。ブレークポイントを Button1_Click
    ハンドラの最初のカッコ( { )に設定して、Update ボタンをクリックするとそこで
    ブレークします。そこで[デバッグの停止]で実行を止めても、DB は UPDATE され
    ます。

     

    ASP.NET 開発サーバーでもローカル IIS でも同じです。

     

    DB はソリューションエクスプローラの App_Code を右クリックし、[新しい項目の
    追加]から[SQL データベース]を選択して作り、データーベースエクスプローラで
    [新しいテーブルの追加]で作成しています。内容は以下の通りです。

     

    id      int            主キー, IDENTITY の指定:はい
    name    varchar(50)
    price   money
    memo    varchar(50)    NULL 許可

     

    とりあえずご報告まで。

     

    Code Snippet

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data.SqlClient" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <script runat="server">

        protected void Button1_Click(object sender, EventArgs e)
        {
            string connString = ConfigurationManager.ConnectionStrings["databaseConnectionString"].ConnectionString;
            string query = "UPDATE [table] SET [name] = @name WHERE [id] = @id";
            SqlConnection connection = new SqlConnection(connString);
            SqlCommand command = new SqlCommand(query, connection);
            command.Parameters.AddWithValue("@name", "ZZZZZZZZ");
            command.Parameters.AddWithValue("@id", 1);
            try
            {
                connection.Open();
                command.ExecuteNonQuery();
            }
            finally
            {
                connection.Close();
            }       
        }

        protected void Button2_Click(object sender, EventArgs e)
        {

        }
    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Update" />
            <asp:Button ID="Button2" runat="server" Text="DoNothing" onclick="Button2_Click" />
        </div>
        </form>
    </body>
    </html>

     

     

     

    2008年12月6日 6:17
  •  バックスマッシュさん、皆さん、こんにちは。
    バックスマッシュさん、返信を下さりありがとうございます。

     

    >ブレイクした時点では、DBへの接続はどうなっていますか?
    >DBサーバーにてコネクション状態を確認してみて下さい。

     

    コネクション状態の確認方法が分からずにいます。SQL Expressに付属のツールを使えばわかりそうですが、それらしきツールが見当たりません。

     

    >この確認は、IISとDBサーバーを再起動してDBへの接続をクリアし、
    >DBサーバーにてコネクションがないのを確認してから行うとよりよいと思います。

     

    IISはASP.Net開発サーバを中止して、DBサーバーは再起動してIDEのサーバーエクスプローラーでデーターベースを切断してから実行しても書き込まれてしまいます。
    もっとも、サーバーエクスプローラーでは何回切断しても”データ接続”-”*.MDF”のコンテキストメニューの”最新の情報に更新”を選択すると接続している状態になります。

     

    >他に、ブレイクポイント到達前に同じ処理があって、
    >それがたまたま実行されていたりしていませんか?

     

    これは、俺も最初に疑いまして調べたのですがそんなことはありませんでした。

     

    >別のアプローチとしては、そのSQLが更新するデータをあらかじめロックし、
    >その状態で試す方法があります。

     

     ロックするとはどのようにすればいいのかわからず戸惑っています。どなたか何かヒントでもいただけると嬉しいのですが・・・

     

     実力不足でご迷惑をおかけして申し訳ありません。
    宜しくお願いします。

    2008年12月6日 6:59
  • SurferOnWwwさん、みなさん、こんにちは。
    SurferOnWwwさん、返信を下さりありがとうございます。

     

    #バックスマッシュさんへの返信を作成し始めた時には
    #SurferOnWwwさんの書き込みが無かったのですが、バックスマッシュさんへの
    #返信を投稿したらSurferOnWwwさんの書き込みがされていました。
    #結果的にSurferOnWwwさんの投稿の後に俺のバックスラッシュさんへの
    #返信が投稿される形になってしまいました。

     

    該当するMDFのプロパティで確認したところ下のようにSQLEXPRESSになっていました。
    Data Source=.\SQLEXPRESS; ... User Instance=True

     

    自分の環境ですが、あれからパッチを充てまして下のようになりました。
    Vista SP1 + .NET 3.5 SP1 + VS2008 Pro SP1 + SQL Server 2008 Express

     

     パッチを充てても①のブレークポイントで停止して、そこで停止ボタンを押すと書き込まれてしまいます。

    strSqlStatementにエラーが発生するようにクエリを代入したところブレークした場所で停止ボタンを押すと書き込みは行われずIDEからコードのデータベースへの書き込み箇所でエラーメッセージもでませんでした。(その前で停止しているから当たり前といえば当たり前なのですが・・・)

     

    ただ、これバグみたいなもんなんですね。

    SurferOnWwwさん、多大な労力を費やさせてしまいまして大変申し訳ありませんでした。

     

     これによりプログラミングが中断していたので本当に助かりました。

    SurferOnWwwさん、皆さん、ありがとうございました。

    2008年12月6日 14:15
  • さらに調べてみましたが、どうも[デバッグの停止]でデバッガのコント
    ロールが外れて、コードが勝手に走っていってしまうような感じで、SQL
    Server への書き込みに限った話ではなさそうです。

     

    ASP.NET ではなく Visual Studio の話と思いますので、Visual Studio
    共通フォーラムの方で、他の皆さんにそのような現象は出ていないか聞

    いてみることにします。

    2008年12月8日 11:46
  •  
    こちらに書いておきましたが、Visual Studio では(開発効率をあげるために、)そのような挙動をするようになっています。
    どうしても、強制中断する機能が必要な場合は、Professinal 版とのことですので、ネイティブデバッグを有効にして運用するという手段があります。
     
    2008年12月8日 16:08
  • K.Takaokaさん、みなさん、こんにちは。
    K.Takaokaさん、返信を下さりありがとうございます。

     

     開発効率を上げるためだったのですね。

    K.Takaokaさん、SurferOnWwwさんや皆さんのお陰でこの事に対する理解も深まりました。

     

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

    2008年12月13日 2:06