Of course it is a bad example, but that's not the point, the point is if we
should close our Recordset objects before releasing them or not, here are
some related links from MSDN:
Improving MDAC Application Performance
Coding Techniques and Programming Practices
25+ ASP Tips to Improve Performance and Style
Eric Garza, MVP
Release Unused ADO Objects
Whenever possible, release ADO objects as soon as you're done with them.
This frees up the database and other resources that might be expensive to
hold for an extended period. Explicitly close all objects rather than
allowing the object to close itself as it is destroyed.
a.. Tune the RecordSet.CacheSize property to what is needed. Using too
small or too large a setting will adversely impact the performance of an
b.. Bind columns to field objects when looping through recordsets.
c.. For Command objects, describe the parameters manually instead of using
Parameters.Refresh to obtain parameter information.
d.. Explicitly close ADO Recordset and Connection objects to insure that
connections are promptly returned to the connection pool for use by other
e.. Use adExecuteNoRecords for non-row-returning commands.
Tip 8: Acquire Resources Late, Release Early
Here's a short tip for you. In general, it's best to acquire resources late
and release them early. This goes for COM objects as well as file handles
and other resources.
ADO Connections and recordsets are the prime candidates for this
optimization. When you are done using a recordset, say after painting a
table with its data, release it immediately, rather than waiting until the
end of the page. Setting your VBScript variable to Nothing is a best
practice. Don't let the recordset simply fall out of scope. Also, release
any related Command or Connection objects. (Don't forget to call Close() on
recordsets or Connections before setting them = Nothing.) This shortens the
time span in which the database must juggle resources for you, and releases
the database connection to the connection pool as quickly as possible."
> Of course, the above is a bad example, but the principle (COM's AddRef()
> Release() having a bearing on whether or not a recordset should be closed)
> is the same.
> In the real world, Class A would be handing out Clone()'s of the
> > I'd also have to disagree, even with VB.
> > Class A has a global member, m_rs of type ADODB.Recordset, and a
> > called Recordset, which returns m_rs to the caller. Class A initializes
> > m_rs with some data from a datasource.
> > Class B calls Class A's property to retrieve the recordset
> > Class C calls Class A's property to retrieve the recordset
> > Class B terminates and explicitly closes the recordset
> > Class C now has a closed recordset, and who's to say whether Class C
> > *wanted* it closed?
> > Only the Recordset itself knows when its refcount reaches zero, and in a
> > world where pointers to objects can be handeded out ad-hoc, I personally
> > think its an incredibly BAD idea to explicitly close a recordset except
> > cases where you absolutely positively know that nobody else has a copy
> > it.
> > PS. Class A's destructor cannot explicitly close m_rs either, since
> > classes may still be using the recordset after Class A goes out of
> > --
> > Robert Simpson
> > Programmer at Large
> > Black Castle Software, LLC
> > http://www.blackcastlesoft.com
> > > You are right, but that was C++ and I was talking VB.
> > > Experience tells me that it's better if you close them explicitly and
> > > don't think I'm alone.
> > > Also, I understand that it could be a problem with the implementation
> > the
> > > destructors, but that is MS business, mine is to deliver robust
> > > applications.
> > > --
> > > Regards,
> > > Eric Garza, MVP
> > > Project manager
> > > AMI GE
> > > > > It's a matter of good programming practices, you shouldn't rely on
> > > > > destructor doing the close.
> > > > I don't recognize that as good programming practice for 3 reasons:
> > > > 1. Consider the ISO C++ file stream objects: ifstream, fstream,
> > > > The destructors are _guaranteed_ to release buffers, close files
> > > > they have been designed to clean up after themselves. That is the
> > > > behaviour of a well written C++ object. The same could be said
> > > basic_string,
> > > > stringstream's and all the container classes (vector, list, map).
> > > > programmer does not have to manually clean up and if they did, it
> > be
> > > > error prone.
> > > > 2. Consider a pending exception. If what you said was true, then you
> > would
> > > > have to write messy try-catch clauses to make your code exception
> > > > These would be necessary -- just to close the Recordset before the
> > > > destructor gets fired because the object is going out of scope.
> > > > 3. It goes against the grain of "resource acquisition is
> > > > technique as popularised by Stroustrup in 2nd/3rd edition. The point
> > about
> > > > the technique, in that resources are released in the destructor is
> > it
> > > > is _not_ error prone and is _guaranteed_ to release resources
> > the
> > > > object is terminating normally or because an exception is being
> > > > Ideally the RecordSet SmartPtrs that Microsoft have provided (which
> > > like)
> > > > would clean up after themselves. The bare minimum would be that
> > RecordSets
> > > > would be closed, Connection pointers would be closed, Com objects
> > be
> > > > Release()'d.
> > > > I believe that the smart pointers are well written but it is
> > undocumented
> > > as
> > > > to how well they behave and what the destructors do.
> > > > Cheers
> > > > Stephen Howe