開発マシンでは問題なく動作する VB.NET アプリがありますが、サーバーで断続的なエラーが発生します。イベント ログは以下のとおりです (これが投稿する必要があるものより多い場合は申し訳ありませんが、私の問題の 1 つはイベント ログを解釈することです)。
2 人以上が同時に Web アプリを実行すると、サーバーでエラーが発生するようです。多くの場合、ハングしているように見えてからタイムアウトします。その後、戻ってアプリを実行しようとすると、サーバーで Web サイトを再起動するまで、以下のエラーが表示されます。これまでのところ、アプリを実行しているのは 1 人だけであれば問題ありません。私のサーバー ベンダーは、これが (メモリ、サーバーなどではなく) アプリ エラーであることを示していると示しています。アプリは入力データを取得し、(ADODB を使用して) 複数の MS Access データベースにクエリを実行し、AJAX を介していくつかの値を返します。これは、実行に数秒かかるかなり集中的な計算アプリです。
エラーが発生したコードを提供する必要があることはわかっていますが、最初の問題は、イベント ログの読み方がわからないことです。エラーイベントが発生したことを教えてくれるのはどこですか? データベースにヒットすることと関係があると思いますか?
現在、データの読み取りのみを行っているため、データベースが何らかの形でロックされる可能性はないと思いますか? 複数の接続を開いたり、複数のレコードセットを開いたり、データベースクエリごとに開いたり閉じたりしたことはないと思います(これも開発マシンで動作します)。では、複数のユーザーと関係があるように見えますか?
一般的に、データベースやアプリに同時にアクセスする人を心配する必要はないと思いましたか? それとも、これらのエラーをキャッチするために、問題のあるコードの周りに常に Try/Catch を配置する必要がありますか?
また、これが正常なのか、問題に関連しているのかはわかりません。イベント ログには、サーバーからではなく、私の開発マシン (C:\MyFiles... で始まるパス) からのパスが表示されます。サーバーはこれらのパスをどのように認識していますか? これは、サーバーにアップロードされるバイナリ DLL に格納されるものですか?
繰り返しますが、詳しい情報を提供できなかった場合は、事前にお詫び申し上げます。しかし、これらの予備的な質問によって、問題の原因に近づくことができるかもしれません。これは便利なフォーラムのようです。
前もってありがとう、チャック
注: 一部の IP アドレスはマスクされています
Log Name: Application
Source: ASP.NET 4.0.30319.0
Date: 8/6/2013 2:48:00 PM
Event ID: 1309
Task Category: Web Event
Level: Warning
Keywords: Classic
User: N/A
Computer: 358797-web1
Description:
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 8/6/2013 2:48:00 PM
Event time (UTC): 8/6/2013 7:48:00 PM
Event ID: ca3280fb485345c194349a42e6e81a85
Event sequence: 66
Event occurrence: 11
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/12/ROOT-1-130202909916484475
Trust level: Full
Application Virtual Path: /
Application Path: C:\inetpub-illustrations\wwwroot\
Machine name: 358797-WEB1
Process information:
Process ID: 760
Process name: w3wp.exe
Account name: NT AUTHORITY\SYSTEM
Exception information:
Exception type: COMException
Exception message: Operation is not allowed when the object is open.
at ADODB.ConnectionClass.set_ConnectionString(String pbstr)
at clsCalc_IllustrationValues.mod_DLLUtilities.util_OpenMyDBConnection(String& strDBName,
String& strPassword) in C:\MyFiles\Visual Studio Projects
\clsCalc_IllustrationValues\mod_DLLUtilities.vb:line 130
at clsCalc_IllustrationValues.clsConvertedActVal.GetPlanData(Int32& eLOB_ActValCalcs,
usrUserInputType& usrUserInput, usrPolicyValuesType& usrPolicyValues) in C:\MyFiles\Visual
Studio Projects\clsCalc_IllustrationValues\clsConvertedActVal.vb:line 2668
at clsCalc_IllustrationValues.clsConvertedActVal.TradSolve() in C:\MyFiles\Visual Studio
Projects\clsCalc_IllustrationValues\clsConvertedActVal.vb:line 2063
at clsCalc_IllustrationValues.clsActValDotNet.DoSingleSolve(DataSet dsDataSet) in
C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues \clsActValDotNet.vb:line 945
at _Default.CallSingleSolve() in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 2997
at _Default.InitializeAllControls() in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line
354
at _Default.Page_Load(Object sender, EventArgs e) in C:\inetpub-
illustrations\wwwroot\Default.aspx.vb:line 65
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Request information:
Request URL: http://xx.xx.xx.250/Default.aspx
Request path: /Default.aspx
User host address: xx.xx.xx.91
User:
Is authenticated: False
Authentication Type:
Thread account name: NT AUTHORITY\SYSTEM
Thread information:
Thread ID: 18
Thread account name: NT AUTHORITY\SYSTEM
Is impersonating: False
Stack trace: at ADODB.ConnectionClass.set_ConnectionString(String pbstr)
at clsCalc_IllustrationValues.mod_DLLUtilities.util_OpenMyDBConnection(String& strDBName, String& strPassword) in C:\MyFiles\Visual Studio Projects \clsCalc_IllustrationValues\mod_DLLUtilities.vb:line 130
at clsCalc_IllustrationValues.clsConvertedActVal.GetPlanData(Int32& eLOB_ActValCalcs, usrUserInputType& usrUserInput, usrPolicyValuesType& usrPolicyValues) in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues\clsConvertedActVal.vb:line 2668
at clsCalc_IllustrationValues.clsConvertedActVal.TradSolve() in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues\clsConvertedActVal.vb:line 2063
at clsCalc_IllustrationValues.clsActValDotNet.DoSingleSolve(DataSet dsDataSet) in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues \clsActValDotNet.vb:line 945
at _Default.CallSingleSolve() in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 2997
at _Default.InitializeAllControls() in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 354
at _Default.Page_Load(Object sender, EventArgs e) in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 65
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Custom event details:
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="ASP.NET 4.0.30319.0" />
<EventID Qualifiers="32768">1309</EventID>
<Level>3</Level>
<Task>3</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2013-08-06T19:48:00.000Z" />
<EventRecordID>30445</EventRecordID>
<Channel>Application</Channel>
<Computer>358797-web1</Computer>
<Security />
</System>
<EventData>
<Data>3005</Data>
<Data>An unhandled exception has occurred.</Data>
<Data>8/6/2013 2:48:00 PM</Data>
<Data>8/6/2013 7:48:00 PM</Data>
<Data>ca3280fb485345c194349a42e6e81a85</Data>
<Data>66</Data>
<Data>11</Data>
<Data>0</Data>
<Data>/LM/W3SVC/12/ROOT-1-130202909916484475</Data>
<Data>Full</Data>
<Data>/</Data>
<Data>C:\inetpub-illustrations\wwwroot\</Data>
<Data>358797-WEB1</Data>
<Data>
</Data>
<Data>760</Data>
<Data>w3wp.exe</Data>
<Data>NT AUTHORITY\SYSTEM</Data>
<Data>COMException</Data>
<Data>Operation is not allowed when the object is open.
at ADODB.ConnectionClass.set_ConnectionString(String pbstr)
at clsCalc_IllustrationValues.mod_DLLUtilities.util_OpenMyDBConnection(String& strDBName, String& strPassword) in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues\mod_DLLUtilities.vb:line 130
at clsCalc_IllustrationValues.clsConvertedActVal.GetPlanData(Int32& eLOB_ActValCalcs, usrUserInputType& usrUserInput, usrPolicyValuesType& usrPolicyValues) in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues\clsConvertedActVal.vb:line 2668
at clsCalc_IllustrationValues.clsConvertedActVal.TradSolve() in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues\clsConvertedActVal.vb:line 2063
at clsCalc_IllustrationValues.clsActValDotNet.DoSingleSolve(DataSet dsDataSet) in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues \clsActValDotNet.vb:line 945
at _Default.CallSingleSolve() in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 2997
at _Default.InitializeAllControls() in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 354
at _Default.Page_Load(Object sender, EventArgs e) in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 65
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
</Data>
<Data>http://xx.xx.xx.250/Default.aspx</Data>
<Data>/Default.aspx</Data>
<Data>xx.xx.xx.91</Data>
<Data>
</Data>
<Data>False</Data>
<Data>
</Data>
<Data>NT AUTHORITY\SYSTEM</Data>
<Data>18</Data>
<Data>NT AUTHORITY\SYSTEM</Data>
<Data>False</Data>
<Data> at ADODB.ConnectionClass.set_ConnectionString(String pbstr)
at clsCalc_IllustrationValues.mod_DLLUtilities.util_OpenMyDBConnection(String& strDBName, String& strPassword) in C:\MyFiles\Visual Studio
Projects\clsCalc_IllustrationValues\mod_DLLUtilities.vb:line 130
at clsCalc_IllustrationValues.clsConvertedActVal.GetPlanData(Int32& eLOB_ActValCalcs, usrUserInputType& usrUserInput, usrPolicyValuesType& usrPolicyValues) in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues\clsConvertedActVal.vb:line 2668
at clsCalc_IllustrationValues.clsConvertedActVal.TradSolve() in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues\clsConvertedActVal.vb:line 2063
at clsCalc_IllustrationValues.clsActValDotNet.DoSingleSolve(DataSet dsDataSet) in C:\MyFiles\Visual Studio Projects\clsCalc_IllustrationValues \clsActValDotNet.vb:line 945
at _Default.CallSingleSolve() in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 2997
at _Default.InitializeAllControls() in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 354
at _Default.Page_Load(Object sender, EventArgs e) in C:\inetpub-illustrations\wwwroot\Default.aspx.vb:line 65
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
</Data>
</EventData>
</Event>
フォローアップの更新(ヘルプを見ました - 元の質問を編集することで、これを正しく行っていると思います。別の方法でフォローアップする必要があるかどうかを教えてください)。問題を絞り込もうとしていることは他にもありますが(回答を待っている人がいるかどうかはわかります)、求められたコードで更新したかったのです。
まず、上記の機密情報を編集していただきありがとうございます。それが問題であることに気づきませんでした。とにかく、コードの古い部分 (エラーがあったと思われる場所) が別のコードを使用してデータベースにアクセスしていることを発見したので、それを更新して統合し、すべてのデータベース アクセスが同じコードで行われるようにしました。
Private Function GetDataSet_ODBC() As System.Data.DataSet
Dim dsDataSet As New System.Data.DataSet
If Me.bWriteToTraceFile Then Me.WriteToTextFile("START GetDataSet_ODBC", System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", False)
Dim DataAdapter As New System.Data.Odbc.OdbcDataAdapter
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" Created DataAdapter", System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
Dim i As Integer
Dim iUBound As Integer
Dim iRetryCount As Integer
Dim dStart As Double
Dim dFinish As Double
DataAdapter.SelectCommand = New System.Data.Odbc.OdbcCommand
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" Created new command", System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
With DataAdapter.SelectCommand
.CommandType = CommandType.StoredProcedure
.Connection = New System.Data.Odbc.OdbcConnection
.Connection.ConnectionTimeout = 15
.Connection.ConnectionString = "Driver={Microsoft Access Driver (*.mdb)};" & _
"DBQ=" & tDBPath & tDBName & ";UID=;PWD=" & tDBPassword
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" ConnectionString=" & .Connection.ConnectionString, System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
End With
DataAdapter.InsertCommand = New System.Data.Odbc.OdbcCommand
With DataAdapter.InsertCommand
.CommandType = CommandType.StoredProcedure
.Connection = DataAdapter.SelectCommand.Connection
End With
DataAdapter.SelectCommand.Connection.Open()
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" Connection opened", System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
iUBound = UBound(usrProcedures)
For i = 0 To iUBound
DataAdapter.SelectCommand.CommandText = "Execute " & usrProcedures(i).tName & " " & usrProcedures(i).tParameters
iRetryCount = 0
Do
Try
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" Executing... " & Str(i) & " " & usrProcedures(i).tName, System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
DataAdapter.Fill(dsDataSet, usrProcedures(i).tTableName)
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" Wrote to " & usrProcedures(i).tTableName, System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
Exit Do
Catch
iRetryCount += 1
If iRetryCount = 25 Then
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" Still won't work", System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
Exit Do
End If
dStart = Microsoft.VisualBasic.DateAndTime.Timer
dFinish = dStart + 1
Do Until Microsoft.VisualBasic.DateAndTime.Timer > dFinish
Loop
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" Try again " & Str(iRetryCount) & " " & Str(dStart) & Str(Microsoft.VisualBasic.DateAndTime.Timer), System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
End Try
Loop
Next
DataAdapter.SelectCommand.Connection.Close()
If Me.bWriteToTraceFile Then Me.WriteToTextFile(" Connection closed", System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
DataAdapter = Nothing
If Me.bWriteToTraceFile Then Me.WriteToTextFile("FINISH GetDataSet_ODBC", System.AppDomain.CurrentDomain.BaseDirectory & "..\TraceFiles\TraceODBC.txt", True)
Return dsDataSet
End Function
また、速度を上げるために「DEBUG」をオンにせずに、ビルドされたコードをサーバーに昇格させました。デバッグ中の間違いかもしれません (元に戻します)。2 人のユーザーが同時にデータベースにアクセスすると、2 番目のユーザーにハングアップするだけです。ただし、2 番目の人のブラウザーを閉じて戻って、Web サイトを再起動しなくてもアプリを正常に実行できるようになりました。再試行の回数を試し、トレース ファイルを作成してどこで問題が発生したかを調べていますが、何か問題が発生する可能性があります。
参考までに - 上記のコードは、格納された Access パラメーター クエリの名前、パラメーター、および返されるデータ テーブルの名前を持つ usrProcedure() の配列を受け入れます。データセットには、10 ものほとんど小さなテーブル (多くは 1 つのレコードのみ、おそらく 1 つまたは 2 つの 100 レコード) が返される場合があります。数回だけデータベースにアクセスしようとしていますが、一度に大量のデータを取得しすぎているのではないでしょうか? しかし、私はかなり強力なサーバーを持っています (私が思うに) (専用の Window Server 2008 Enterprise、バージョン 6.0 ビルド 6002、SP2、64 ビット、8 GB RAM、AMD 2200 Mhz 4 コア プロセッサ - 現時点ではほとんどトラフィックがなく、Rackspace によってホストされています)。
とにかく、私は推測しています (しかし、トレースを介して確認しようとします)、2 番目の男は、トライをループして終了し、データがないために後でハングするか、トライにハングします。
最後に、このデータベース アクセス コードを 2 つの場所 (1 つは入力制御データを取得するため、もう 1 つは計算を行うため) でヒットしました。コンパイルされていない分離コード ページから初めてコードが呼び出されたとき。それはハングすることはありません (ただし、それ以上ではないにしても、ほぼ同じ量のデータにアクセスします)。上記のコードは、コンパイルされた DLL の「ユーティリティ」プロジェクトにあります。2 回目は、計算を行う別の DLL プロジェクトからこのコードが呼び出されます。これは物事がハングアップする場所です。それが関連しているかどうかはわかりませんが、すべてのパターン/手がかりをリストしようとしています.
リストされたコードは手がかりを提供しますか?
前もってありがとう、チャック
フォローアップアップデート #2OK、エラーが実際に発生する場所を特定するために、コード全体でトレース ファイル (ファイル名の一部として SessionID を使用) を書きました。依然として発生する問題は、2 人のユーザーが同時にアプリケーションにヒットした場合です。1 つは正常に実行され、もう 1 つは未処理の 3005 エラーです。ただし、現在のエラーは、上記の「開こうとしている」エラーではありません (どうやらそれを修正したようです)。現在、3005 エラーはコードのさまざまなポイントで発生しており、通常はイベント ビューアーで、ある行に null 変数があることを示しています。各ユーザーは同じリクエストを行っているため、同じ結果が得られるはずです。私のトレース ファイルは、両方のユーザー インスタンスでデータベースから同じ数のレコードを読み取っていることを示していますが、データを読み取った後、いずれかのインスタンスでエラーが発生します。たくさんのコードがあり、さまざまな場所でエラーが発生します。だから何を投稿すればいいのかわからない。現在、Global.asax ファイルでエラーをキャプチャして、ユーザーをリダイレクトして再ログインし、アプリケーションを再度実行しています。単独で実行すると、アプリは 2 回目に正常に実行されます。
2 つのインスタンスが互いに完全に独立しておらず、一方が他方からオブジェクトまたはデータを何らかの形で消去しているように見えます。リクエストがサーバーにヒットした正確なタイミングに基づいて、さまざまなポイントでエラーが発生するようです。トレース ファイルに記録した日付スタンプは、一方のインスタンスが他方のインスタンスがいつリクエストを終了したかについてエラーを起こしていることを示しているようです。共有ルーチンを確認し、それらを削除しました。呼び出された DLL の各インスタンスが「新規として」宣言されていることを確認しました。また、トレース ファイルに書き込まれた行が、コードどおりに表示されるとは限らないことに気付きました。
ASP.NET は、私が特別なことをしなくてもコードの非同期実行を自動的に行いますか? 複雑に見えるので、非同期処理を明示的に実行しようとはしていませんが、ここで何かを管理する必要がありますか?
他に何を探すべきですか?
よろしくお願いします