Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

FIX: An Access Violation Occurs in ADO Under Heavy Stress with .NET COM Interop or Java


View products that this article applies to.

This article was previously published under Q321415
Caution ADO and ADO MD have not been fully tested in a Microsoft .NET Framework environment. They may cause intermittent issues, especially in service-based applications or in multithreaded applications. The techniques that are discussed in this article should only be used as a temporary measure during migration to ADO.NET. You should only use these techniques after you have conducted complete testing to make sure that there are no compatibility issues. Any issues that are caused by using ADO or ADO MD in this manner are unsupported. For more information, see the following article in the Microsoft Knowledge Base:
840667 (http://support.microsoft.com/kb/840667/ ) You receive unexpected errors when using ADO and ADO MD in a .NET Framework application

↑ Back to the top


Symptoms

In a Microsoft .NET program that uses ActiveX Data Objects (ADO) through COM Interop, or in a Java program that uses ADO, an access violation may occur when you call the Close method of the ADO Connection object. The access violation occurs only under heavy stress when multiple threads are connecting to and disconnecting from the backend database server. This issue is not specific to any particular OLE DB provider or ODBC driver.

↑ Back to the top


Cause

Each ADO Connection object internally maintains a collection of Recordset and Command objects that are associated with that connection. Each Recordset object also maintains a reference to its associated Command objects. When the connection is closed, it cleans up its objects and releases the references that it is holding. While the Connection object is cleaning up its collection of Recordset and Command objects, a race condition can occur between the Recordset object's reference on the Command object and the Connection object's reference on the Command object. The nondeterministic timing of garbage collection in .NET and Java eventually triggers the race condition that causes the access violation. The following call stack is typical when the problem occurs:
ChildEBP RetAddr  Args to Child              
00aaf6d8 1f447532 00000020 0f648448 1f436fc9 msado15!CExecInfo::Term+0x44
00aaf6e4 1f436fc9 0f5d8a14 0f5d8a14 0f5d8ab8 msado15!CExecInfo::Init+0x9 
00aaf710 1f437111 0f5d8a14 0f5d8a08 1f437216 msado15!CParameters::GetAvailableOutputParams+0xd3
00aaf71c 1f437216 0f5ee274 0f5ee190 00000000 msado15!CParameters::EmptyParameters+0x9
00aaf758 1f43a5c5 00aaf984 0f5ee190 001405a8 msado15!CCommand::Close+0x2f
00aaf828 1f44494b 00aaf880 00000002 00000000 msado15!CConnection::_Close+0x348
00aaf830 00000002 00000000 00000000 00000000 msado15!CConnection::Close+0x8d

↑ Back to the top


Resolution

To resolve this problem, obtain the latest service pack for Microsoft SQL Server 2000. For additional information, click the following article number to view the article in the Microsoft Knowledge Base:
290211� INF: How to Obtain the Latest SQL Server 2000 Service Pack
The English version of this fix should have the following file attributes or later:
   Date         Time   Version      Size     File name
   -----------------------------------------------------
   16-Apr-2002  12:49  2.70.8616.0  753,664  Msado15.dll

↑ Back to the top


Status

Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article. This problem was first corrected in Microsoft SQL Server 2000 Service Pack 3.

↑ Back to the top


More information

In addition to the fixed version of the msado15.dll file, you can use the following two coding practices when you are programming with ADO in a language that is subject to garbage collection. These practices reduce the likelihood of this problem.
  • Explicitly release references to COM objects when you are finished using them.

    In .NET languages such as Microsoft Visual C# .NET and Microsoft Visual Basic .NET, you can do this by calling the ReleaseComObject method. The following C# example demonstrates this method:
    //m_connection is an ADODB.ConnectionClass object
    if( m_connection != null && 
         m_connection.State == ( int )ADODB.ObjectStateEnum.adStateOpen )
    {
         try
         {
              m_connection.Close();
              Marshal.ReleaseComObject(m_connection);
         }
         catch (COMException e )
         {
              Console.WriteLine( "Error - " + e.Message );
         }
    }
    m_connection = null;
    In Java, you do this by using a call to the release method that is defined in the com.ms.com.ComLib class. For additional information about this method and other coding practices for using COM in Java, click the article number below to view the article in the Microsoft Knowledge Base:
    296994� PRB: Java Components May Perform Poorly in COM+
  • Use the ADO primary interop assembly. When you use ADO through COM Interop in .NET, use the ADO primary interop assembly instead of creating your own wrapper classes by using the Type Library importer (Tlbimp.exe). The problem that is described in this article may occur whether you use the primary interop assembly or the classes that are generated by Tlbimp, but in general it is a good idea always to use the primary interop assembly. For additional information, click the article number below to view the article in the Microsoft Knowledge Base:
    318559� INFO: Using the Primary Interop Assembly for ADO (ADODB) in Visual Studio .NET
    When you use the primary interop assembly, the compiler permits several different object names for the various ADO objects. For ADO to work properly, the classes that you use must all contain the word "Class" at the end of the class name. For example:
    ADODB.ConnectionClass
    ADODB.RecordsetClass
    ADODB.CommandClass
    When you use these objects, use ReleaseComObject as described earlier in this article so that COM has an opportunity to release the reference.

↑ Back to the top


Keywords: kbhotfixserver, kbqfe, kbsqlserv2000sp3fix, kbbug, kbfix, kbsqlserv2000presp3fix, KB321415

↑ Back to the top

Article Info
Article ID : 321415
Revision : 5
Created on : 11/29/2007
Published on : 11/29/2007
Exists online : False
Views : 367