When using Windows Foundation Classes for Java (WFC) and ADO, and opening
a recordset using a parameterized command object, connections that are
properly closed are not properly pooled and recycled, resulting in
To work around this problem, call System.gc() after closing the ADO connection in
your Java COM object. In normal situations, you do not need to call System.gc()
after closing an ADO connection in order to free the connection.
This problem is fixed in the latest service packs for Windows 2000 and MDAC 2.5.
- To resolve this problem, obtain the latest service pack for Windows 2000. For additional information, click the following article number to view the article in the
Microsoft Knowledge Base:
How to Obtain the Latest Windows 2000 Service Pack
- To resolve this problem, obtain the latest service pack for Microsoft Data Access Components 2.5. For additional information, click the following article number to view the article in the
Microsoft Knowledge Base:
INFO: How to Obtain the Latest MDAC 2.5 Service Pack
The English version of this fix should have the following file attributes or later:
File name Date Size Version
Msado15.dll 1/26/2000 329KB 2.12.4926.0
Microsoft has confirmed that this is a problem in Microsoft Data Access Objects2.1 SP2 and 2.5. This problem was first corrected in Microsoft Data Access Components 2.5 Service Pack 2 and Microsoft Windows 2000 Service Pack 2.
This connection/session pooling issue occurs when all of the following conditions are present:
- Microsoft Data Access Objects 2.1 SP2 is installed.
- A parameterized ADO Command object is used.
- The Java COM object is hosted in MTS or COM+.
- The Java COM object creates a disconnected recordset.
Steps to Reproduce the Behavior
- Create a Java COM object project named ConnLoss with Visual J++ 6.0 using the following code:
public class ConnLoss
// Modify this connection string to point to a running SQL Server.
private static String m_connect =
FindAuthorsLastName( String au_id, boolean fCallGC )
Connection conn = null;
Command cmd = null;
Recordset rs = null;
// Open connection to SQL Server.
conn = new Connection();
conn.setCursorLocation( AdoEnums.CursorLocation.CLIENT );
conn.open( m_connect );
// Prepare command object.
cmd = new Command();
cmd.setActiveConnection( conn );
cmd.setCommandText( "select au_lname from authors where au_id=?" );
20, au_id ) );
// Execute command.
rs = cmd.execute();
// Disconnect recordset and close connection.
rs.setActiveConnection( (Connection) null );
// Call gc if requested.
if (fCallGC) System.gc();
// Return disconnected recordset.
return (com.ms.wfc.data.adodb._Recordset) rs.getDataSource();
catch( AdoException adoEX )
// Log errors here.
- Add the Java COM object to MTS or the COM+ package.
- Call the Java COM object with the following Microsoft Visual Basic for Applications (VBA) code:
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)
Set rs = Nothing
- Run Windows NT Performance Monitor on the machine where SQL Server 7.0 is located and monitor User Connections under the SQL Server:General Statistics performance counter.
- Run the VBA client code.
At this point, 100 user connections are generated by the code as reported by Windows NT Performance Monitor, indicating that the OLE DB session pooling is not working properly for the SQL OLE DB provider used by the Java COM object.
- Change the second parameter of FindAuthorsLastName to True in order to activate the System.gc() code.
- Stop and restart the MTS or COM+ package.
- Run the VBA client code a second time.
At this point only a few user connections are generated by the code, indicating that the OLE DB session pooling is working properly for the SQL OLE DB provider used by the Java COM object when System.gc() is called.NOTE
: Calling System.gc() greatly impacts the performance of the Java COM object, so calling System.gc() in general should be avoided when performance is a consideration. For example, the business object could be coded to only call System.gc() every 10 or 100 method calls to reduce the per method performance impact of calling System.gc(). Also, the use of a parameterized command object could be avoided by hard-coding parameter values into a SQL string and not using parameter tokens as in the above example; this circumvents the issue as well.
Article ID: 247757 - Last Review: April 7, 2006 - Revision: 3.0
- Microsoft Data Access Components 2.1 Service Pack 2
- Microsoft Data Access Components 2.5
- Microsoft Visual J++ 6.0 Standard Edition
|kbbug kbfix kbmdac250sp2fix kbqfe kbhotfixserver KB247757|