[FIX] ADO でパラメータ化コマンドを使用すると接続がリークする

文書翻訳 文書翻訳
文書番号: 247757 - 対象製品
この記事は、以前は次の ID で公開されていました: JP247757
この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
すべて展開する | すべて折りたたむ

目次

現象

Windows Foundation Classes for Java (WFC) と ADO を使用しているときに、パラメータ化コマンド オブジェクトを使用してレコードセットを開くと、適切に閉じられている接続が正しくプール、リサイクルされず、その結果接続がリークされます。この問題を回避するには、Java COM オブジェクトで ADO 接続を閉じた後に System.gc() を呼び出します。通常の状況では、ADO 接続を閉じた後にその接続を解放するために System.gc() を呼び出す必要はありません。

状況

Windows 2000

この問題を解決するためのモジュールは、Windows 2000 日本語版 Service Pack 2 以降に含まれています。
Windows 2000 日本語版の最新 Service Pack は、以下の Web サイトから入手できます。
http://www.microsoft.com/japan/windows2000/downloads/servicepacks/sp4/default.asp

詳細

この接続/セッション プーリングの問題は、以下の条件をすべて満たしているときに発生します。
  1. Microsoft Data Access Objects 2.1 SP2 がインストールされている。
  2. パラメータ化 ADO コマンド オブジェクトが使用された。
  3. Java COM オブジェクトが MTS または COM+ でホストされている。
  4. Java COM オブジェクトが切断されたレコードセットを作成する。

問題の再現手順

  1. Visual J++ 6.0 で、以下のコードを使用して、ConnLoss という名前の Java COM オブジェクトを作成します。
    import com.ms.wfc.data.*;
    
    public class ConnLoss
    {
      // 次の接続文字列が実行中の SQL Server を指すように変更します。
      private static String m_connect = 
        "Provider=SQLOLEDB;Server=(Local);Database=Pubs;UID=sa;PWD=;";
      public com.ms.wfc.data.adodb._Recordset 
        FindAuthorsLastName( String au_id, boolean fCallGC )
      {
        Connection conn = null;
        Command cmd   = null;
        Recordset rs  = null;
        try
        {     
          // SQL Server への接続を開きます。
          conn = new Connection();
          conn.setCursorLocation( AdoEnums.CursorLocation.CLIENT );
          conn.open( m_connect );
          
          // コマンド オブジェクトを準備します。
          cmd = new Command();
          cmd.setActiveConnection( conn );
          
          cmd.setCommandText( "select au_lname from authors where au_id=?" );
        
          cmd.getParameters().append( 
            cmd.createParameter( "au_id", 
                       AdoEnums.DataType.VARCHAR,
                       AdoEnums.ParameterDirection.INPUT,
                       20, au_id ) );
          
          // コマンドを実行します。
          rs = cmd.execute();
          
          // レコードセットを切断し、接続を閉じます。
          rs.setActiveConnection( (Connection) null );
          conn.close();
          
          // 必要ならば、gc を呼び出します。
          if (fCallGC) System.gc();
          
          // 切断されたレコードセットを返します。
          return (com.ms.wfc.data.adodb._Recordset) rs.getDataSource();
          
        }
        catch( AdoException adoEX )
        {
          // ここでエラーをログに記録します。
        }
        return null;
      }
    }
    
  2. Java COM オブジェクトを MTS パッケージまたは COM+ パッケージに追加します。
  3. 次の Microsoft Visual Basic for Applications (VBA) コードを使用して、Java COM オブジェクトを呼び出します。
    Sub TestConnLoss()
    Dim objCL As Object
    Dim i As Long
    Dim rs As ADODB.recordset
      set objCL = CreateObject("ConnLoss.ConnLoss")
      For i = 1 To 100
        Set rs = objCL.FindAuthorsLastName("756-30-7391", False)
        Debug.Print rs.Fields("au_lname").Value
        rs.Close
        Set rs = Nothing    
      Next i    
    End Sub
    
  4. SQL Server 7.0 が存在するコンピュータで Windows NT パフォーマンス モニタを実行し、SQL Server:General Statistics パフォーマンス カウンタの User Connections を監視します。
  5. VBA クライアント コードを実行します。 この時点で、Windows NT パフォーマンス モニタが報告しているように、このコードにより 100 個のユーザー接続が生成されます。このことは、Java COM オブジェクトが使用する SQL OLE DB プロバイダに対して OLE DB セッション プーリングが正しく機能していないことを示しています。

  6. System.gc() コードをアクティブにするには、FindAuthorsLastName の 2 番目のパラメータを True に変更します。
  7. MTS パッケージまたは COM+ パッケージを停止し、再開します。
  8. 再度 VBA クライアント コードを実行します。
この時点では、コードにより生成されるユーザー接続はわずかで、System.gc() が呼び出されるときに、Java COM オブジェクトが使用する SQL OLE DB プロバイダに対して OLE DB セッション プーリングが正しく機能していることを示しています。

: System.gc() を呼び出すと、Java COM オブジェクトのパフォーマンスに大きな影響を与えます。したがって、一般的にパフォーマンスの面からは、System.gc() の呼び出しを避ける必要があります。たとえば、メソッドごとに System.gc() を呼び出すことによるパフォーマンスへの影響を軽減するために、10 または 100 個のメソッド呼び出しごとに一度だけ System.gc() を呼び出すビジネス オブジェクトを作成できます。または、ハード コードされたパラメータ値を SQL 文字列に渡し、上記の例のようにパラメータ トークンを使用しないで、パラメータ化コマンド オブジェクトの使用を避けます。これによっても同様に問題を回避できます。

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 247757 (最終更新日 2001-02-28) をもとに作成したものです。

プロパティ

文書番号: 247757 - 最終更新日: 2014年2月23日 - リビジョン: 4.0
この資料は以下の製品について記述したものです。
  • Microsoft Data Access Components 2.1 Service Pack 2
  • Microsoft Data Access Components 2.5
  • Microsoft Visual J++ 6.0 Standard Edition
キーワード:?
kbnosurvey kbarchive kbbug kbfix kbqfe kbmdac250bug kbmts kbgrpdsjava kbado210sp2bug kbhotfixserver KB247757
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com