2009-06-28 44 views
1

Sql Serverで奇妙な問題が発生しました。 私は、Webサービスに接続し、データベースに接続して大量のデータを挿入するポケットPCアプリケーションを持っています。 Webサービスは、接続する各ポケットPCのトランザクションを開きます。毎日午後12時に、異なるポケットPCを持つ15〜20人が同時にウェブサービスに接続し、転送を正常に終了する。 その後、4000の排他ロックに関連付けられた1つのオープントランザクション(アクティビティモニターに表示されます)が残ります。数時間後、それらは消滅し(恐らく何かタイムアウトする)、転送されたデータの一部が削除されます。これらのロックが起こらないようにする方法はありますか?またはプログラムでそれらを認識し、ロック解除を待つか?トランザクションコミットは正常に実行されますが、実行されません。

ありがとうございます。

答えて

0

多くのテストを行っているうちに、デッドロックが発生していることがわかりました。しかし、私はいくつかの独立したテーブルに非常に多くのレコードを挿入するだけなので、理由を見つけることができませんでした。 これらのリンクはビットを助けたが、運に:

http://support.microsoft.com/kb/323630

http://support.microsoft.com/kb/162361

私も小さいものに私の取引を破ったが、私はまだデッドロックを得ました。私は最終的にトランザクションを削除し、コードをソースデータベースから削除しないように変更し、デッドロックをもう取得しませんでした。

教訓として、同時に複数の大きなトランザクションが同じデータベースで同時に実行されている場合は、SQL Serverに問題があること、Oracleについてよくわかりません。

1

SQL Server Profilerを使用すると、トランザクションの開始と終了を含むステートメントを監視できます。また、Microsoft Supportのいくつかのツールは、プロファイラやスクリプトを実行してから優れています。私は/もし私がこれらの更新を見つけることができるかどうかを見ています。

オープントランザクションがある場合は、アクティビティモニターでこれを見ることができるはずなので、サーバを再起動する前に開いているトランザクションがあるかどうかを確認できます。

編集

この問題は、毎日ほぼ同時に起こるように聞こえます。問題が発生する前にそれをオンにしたい場合があります。

+0

ありがとうございました。しかし、プロファイラーは、トランザクションが開始された後にトレースが開始されたときに何の活動も表示しません。 – reticent

+0

正確に。私は今朝追跡を開始しました。私は奇妙なことやロックについて何かを探しています。私が何を確認すべきか知っていますか? – reticent

0

コードで何か間違っていると思われます。コマンドタイムアウトを十分に大きな値に設定しているか、COMMITをスキップしている可能性がありますか?

あなたは実行して、開いているものを取引調べることができます。

DBCC OPENTRAN 
+0

私はコマンドタイムアウトを変更していないので、コミットが実行されたと確信しています(3つのトランザクションがMySql、SqlServer、SqlCEに同時にコミットされているので、他の2つのトランザクションはコミットされます。データを参照してください)。 DBCC OPENTRANは、コミット後に開いているトランザクションを示します。私はそれをコミットするために今何をすべきか分かりません。 – reticent

+0

ここにコードを投稿するのに十分な大きさのコードをカットできますか? –

+0

//すべてのメソッドは、Webサービスによって呼び出され、SqlCEトランザクション内のデバイスプロジェクトから呼び出されます。 public DataService() { mySqlService = new mySqlService(); 接続=新しいSqlConnection(connectionString); connection.Open(); トランザクション= connection.BeginTransaction(); } ... //データを転送する方法 - 彼らは 公共ボイド(){ transaction.Commitを()コミットトランザクションを使用します。 mySqlService.Commit(); connection.Close(); } public void Rollback() { transaction.Rollback(); mySqlService.Rollback(); } – reticent

2

あなたはsp_lockを実行し、あなたが興味を持っているテーブルに開催された任意の排他ロックがあるかどうかを確認するためにチェックすることができ、あなたにSPIDを教えてくれること問題の接続の詳細については、sp_whoまたはsp_who2を使用してください。

また、Management Studioのアクティビティモニタでは、この情報のグラフィカルバージョンが表示され、問題のプロセスを強制終了することもできます。killコマンドを使用すると、クエリエディタで同じことを実行できます。

+0

ありがとうございます。私は再びそれが起こるまで待たなければなりませんでした - 今。 アクティブモニターが示すように、プロセスに関連付けられたオープントランザクションがあります。また、sp_lockを使用すると、このSPIDには約7000のロックがあることがわかります。それは異常ですか?もしそうなら、どうすればそれを防ぐことができますか?または、この取引をコミットする方法はありますか?私の問題に関してはそれを殺すことは選択肢ではないからです。 もう一度ありがとうございます。 – reticent

+0

これは非常に多くのロックです!あなたが探したいものは排他ロックです。これはXとマークされています。なぜなら、それらは基本となるリソースへのすべてのアクセスをブロックするものだからです。 (IX、インテントロック、親オブジェクトのロックを取得する他のユーザーの停止、このプロセスに行がXロックされている場合、その行を含むページと表はIXロックされます)。貪欲なプロセスについては、sp_who2を見て、どこから接続しているのか、アプリケーションが何であるかを調べてください。それはデバッグに役立つはずです。その後、SQLプロファイラのような他のテクニックを使って、デバッグを微調整することができます。 –

+0

そのうち72個がIXであり、他のすべてがXです。sp_who2が示すように、それはWebサービスのユーザーから来ています。ステータスは「スリープ状態」です。私は前回のコードをデバッグしましたが、例外はないと確信しています。すべてのインサートを実行した後にプログラムでチェックできる情報がありますか?これらのロックを回避するためにトランザクションを構成することはできますか? – reticent

0

選択したタイムアウトは、トランザクションがまだテーブルの少なくとも一部をロックして開いていることを示します。

どのようにWebサービスでトランザクションを行っていますか?どのように/あなたのコードでトランザクションをコミットしていますか?

+0

私はSystem.Data.SqlClientを使用しています。私は、トランザクションを開始し、データを挿入し、コミットするポケットPCによって呼び出されたWebメソッドを持っています。メソッド全体はtry/catchブロック内にあり、例外が発生した場合にトランザクションをロールバックします。私はあなたの質問に答えましたか? – reticent

+0

すみません!私は間違っていた。私はMyGeneration.doodadsを使用しています(私はSqlCeデータベースに.Netプロバイダを使用しています)。 doodadsにはトランザクションを処理するTransactionMgrがあります。今日、.Net Sqlプロバイダを使用するようにコード全体を変更し、変更があるかどうかを確認しました。 – reticent

関連する問題