2

開発マシンでは問題なく動作する 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&amp; strDBName, String&amp; strPassword) in C:\MyFiles\Visual Studio    Projects\clsCalc_IllustrationValues\mod_DLLUtilities.vb:line 130
   at clsCalc_IllustrationValues.clsConvertedActVal.GetPlanData(Int32&amp; eLOB_ActValCalcs, usrUserInputType&amp; usrUserInput, usrPolicyValuesType&amp;    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&amp; strDBName, String&amp; strPassword) in C:\MyFiles\Visual Studio
   Projects\clsCalc_IllustrationValues\mod_DLLUtilities.vb:line 130
   at clsCalc_IllustrationValues.clsConvertedActVal.GetPlanData(Int32&amp; eLOB_ActValCalcs, usrUserInputType&amp; usrUserInput, usrPolicyValuesType&amp;    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 は、私が特別なことをしなくてもコードの非同期実行を自動的に行いますか? 複雑に見えるので、非同期処理を明示的に実行しようとはしていませんが、ここで何かを管理する必要がありますか?

他に何を探すべきですか?

よろしくお願いします

4

2 に答える 2

0

問題が見つかりました。うまくいけば、これは同様の問題を抱えている他の誰かを助けるでしょう。

いくつかの重要な変数が、クラス モジュールではなく通常のコード モジュールでグローバルに宣言されていることがわかりました。これらはすべて、Visual Studio ソリューションの 1 つのプロジェクトの一部です。クラス モジュールのコードと変数だけが、サーバー上のユーザーごとに個別に保持されていることに気付きませんでした。私は、それらがすべて同じ DLL ファイルにまとめてコンパイルされるという事実にうんざりしていたので、DLL 全体が「コピーされた」と考えていました。Global.asax でエラーをキャプチャし、セッションを中止し、ページをリダイレクトしたときに気づきました。次に、変数が再初期化されたときに、2 番目のユーザーがすぐに最初のユーザーをエラーにさせていることがはっきりとわかりました (最初は、2 番目のユーザーがエラーを起こしていると思っていました)。少しグーグルすると、私が知る必要があることを教えてくれました。

これは、実際に上記の元のデータベースの問題の原因でもあったと思います。どういうわけか見逃した古いコードが、通常のコード モジュールからデータベースにアクセスしていたため、データベースとの競合が発生していました。そのコードを取り除き、データベースへのアクセスに現在使用しているクラスモジュールからデータを取得するように変換したときに、それは修正されました(ただし、それがどのように修正されたかは当時はわかりませんでした)。

したがって、すべての変数宣言をクラス モジュールに移動し、サブルーチンの通常のモジュール コードに引数を介して変数を渡すように大規模な変更を行った後、問題は修正されました (少なくともこれまでのところ)。

于 2013-08-20T16:11:31.897 に答える
0

発生しているエラーは、既に開いている接続を開こうとしているということです。接続の破棄方法に問題がある可能性があります。コードを見るのはいいでしょう。

また、複数の人が同時に DB にアクセスすることを常に考慮する必要があります。アプリケーションを複数のタブで開いてみてください。同じ問題が発生する可能性があります。

于 2013-08-07T19:26:51.367 に答える