Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with CRecordset::Open method

36 views
Skip to first unread message

Muhammad Owais

unread,
Jan 1, 2004, 12:43:27 AM1/1/04
to
Hi All
I have developed a DLL for database connectivity and manipulation. All of my
applications use this dll. Aproximately after 8000 access (open close) to a
specific table the Open method fails to open the recordset and even 100 or
more retries dont work. Can some one help me out by telling the reason of
the problem? Can it be some limit imposed by odbc driver? I am using Access
Database.

Thanks in advance
Best Regards
Muhammad Owais


David A. Mair

unread,
Jan 1, 2004, 1:04:15 AM1/1/04
to
"Muhammad Owais" <m_o...@hotmail.com> wrote in message
news:e6ceMnC0...@TK2MSFTNGP10.phx.gbl...

> Hi All
> I have developed a DLL for database connectivity and manipulation. All of
my
> applications use this dll. Aproximately after 8000 access (open close) to
a
> specific table the Open method fails to open the recordset and even 100 or
> more retries dont work. Can some one help me out by telling the reason of
> the problem? Can it be some limit imposed by odbc driver? I am using
Access
> Database.

Sounds like a resource leak, maybe yours maybe the database driver's. I
wonder if a table with space for 8000 entries has been filled leaving no
space for any other operations. Just a guess though...


Muhammad Owais

unread,
Jan 1, 2004, 2:11:21 AM1/1/04
to

"David A. Mair" <mair...@hotrmail.com> wrote in message
news:Ohw7Z0C0...@TK2MSFTNGP10.phx.gbl...
My first doubt was resource leak but it fails to open the same table
although i am using lot of other tables. And one thing more This table has
only one record at the moment and open it to just to read that record.


David A. Mair

unread,
Jan 1, 2004, 2:14:53 PM1/1/04
to
"Muhammad Owais" <m_o...@hotmail.com> wrote in message
news:%23UPGUYD...@TK2MSFTNGP11.phx.gbl...

I'm afraid I don't see how that could guarantee it isn't a resource leak.
Sadly, at only 8000 iterations it could be an in-memory table and it might
not even show up in the memory load imposed by your process. Consider an
example that probably isn't what you are doing (in pseudo-code):

int count = 0;
while (open("table"...))
{
count++;
}

printf("%d", count);

This would open "table" as many times as it was able and report that number.
What if the access handle for the table wasn't shared? I don't suppose that
it is required to be and it may be advantageous if it wasn't (serialisation
can take place on the back-end). Now consider another case, more like
yours:

int count = 0;
while (h = open("table"...))
{
close(h);
count++;
}

printf("%d", count);

You would expect this to run forever since it has no obvious resource leaks.
However, it may still fail due to a potential optimisation in the back-end.
What if the close is a lazy operation. Transactional integrety probably
only needs to be enforced on updates so a close may not require a flush.
Therefore, it could be done by the driver in spare time. Now consider a
host that is too busy to have spare time. The pending closes would build up
until, perhaps, they would fill the entire handle list and prevent further
opens form taking place. Now, understand that this would be an example of a
very poor process model. I designed a similar one for completely different
type of technology but we enforced close queue flushing at a high water mark
but only flushed to a low-water mark. This guarantees we don't hog the
resources created at an open and the model works fairly well at preserving
resources while delaying unimportant activity. Therefore, my point really
is that you can't take paired open/close operations (even of the same
object) as a guarantee that there is no resoufce leak since the resource
leak could be unrelated to your pairing of opens and closes or to the nature
of the object being opened and closed.


Tim

unread,
Jan 1, 2004, 7:51:10 PM1/1/04
to
Muhammad,

Hi, I am not too sure what is going on here, but the following code runs ok
(in an OnOk handler for a CDialog).

void CTestAccessDlg::OnOK()
{
CDatabase db;
db.OpenEx(_T("DSN=Test"), CDatabase::noOdbcDialog);
rsTest rs(&db);
int x;
for (x = 0; x < 10000; x++)
{
rs.Open();
while (!rs.IsEOF())
rs.MoveNext();
rs.Close();
}

db.Close();
}

The test database is an Access 2003 DB with 1 table containing 1 record that
has a primary key.

As David has said - every open should always have a close - both on the
database and the recordset (and everything else under the sun). Some code
snippets from you would help along with indication of the access db version.
In the past, access db's have sometimes needed to have an Idle function
called during heavy activity to allow access to catch up - could be it.

Also, check you are not Implicitly opening the database : above the
recordset is constructed as follows:

rsTest rs(&db);

do not do this

rsTest rs;
rs.Open(...); // implicitly opens a database.

The first form passes the open CDatabase instance to the recordset - without
this the recordset will open its own private database connection (as in
second case) which is a big no no. In the second case, if you do not have
matching Closes for each Open, then the database connections implicitly
created will accumulate and cause you app to do strange things - this may be
your problem.

You can also do this:

// in your .h file

rsTest m_rsTest; // no need to use pointers...

// in your .cpp in OnInitDialog

rsTest.m_pDatabase = &m_db; // connect the recordset with the already
open database
rsTest.Open();

Consider using Requery instead of a Close / Open pair IE if all you are
doing is changing either the Filter or Sort spec, then do a Requery, but
note that not all DBMS support this (see CanRestart() in CRecordset). It is
perfectly OK to do either (even Open / Close with a DBMS that supports
Requery() ) - this should not be used as a work around as you do have a real
problem which needs sorting...

Preference should be to use only ever 1 CDatabase instance for all
recordsets in a program - unless you have very good reason EG you have
multiple databases (different DSN's / access files / servers / databases
etc.), or need to run more than one asynchronous query or firehose cursor
simultaneously. I usually keep this one instance in my CWinApp as a matter
of convenience and use a macro such as this:

#define PDBC CDatabase* pdbc = ((appMine*)AfxGetApp())->GetDB()

Some commercial products use the approach of 1 database connection for each
recordset - this causes huge problems with memory consumption and
performance.

HTH
- Tim

"Muhammad Owais" <m_o...@hotmail.com> wrote in message
news:e6ceMnC0...@TK2MSFTNGP10.phx.gbl...

Russ Gray [MS]

unread,
Jan 2, 2004, 7:10:32 PM1/2/04
to
What error do you get when it fails?

Thanks,

Russ Gray
Microsoft Developer Support

This posting is provided "AS IS" with no warranties, and confers no rights.


TT (Tom Tempelaere)

unread,
Jan 3, 2004, 6:37:20 AM1/3/04
to
"Muhammad Owais" <m_o...@hotmail.com> wrote in message
news:e6ceMnC0...@TK2MSFTNGP10.phx.gbl...
> Hi All
> I have developed a DLL for database connectivity and manipulation. All of
my
> applications use this dll. Aproximately after 8000 access (open close) to
a
> specific table the Open method fails to open the recordset and even 100 or
> more retries dont work. Can some one help me out by telling the reason of
> the problem? Can it be some limit imposed by odbc driver? I am using
Access
> Database.

Post a code sample that contains enough to code to illustrate the problem.
It is difficult to say what goes wrong without at least a few lines of code.

Cheers,
Tom.

> Muhammad Owais


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.556 / Virus Database: 348 - Release Date: 26/12/2003


Muhammad Owais

unread,
Jan 12, 2004, 8:26:59 AM1/12/04
to
Sorry I was off for some days. The Exception text is "Memory Allocation
failure"

I searched for this problem on the internet lot of people faced this but
didnt find any answer.

thanks
Regards

"Russ Gray [MS]" <rus...@onlinemicrosoft.com> wrote in message
news:cJ5O93Y0...@cpmsftngxa07.phx.gbl...

Muhammad Owais

unread,
Jan 13, 2004, 7:10:31 AM1/13/04
to

"TT (Tom Tempelaere)" <_N_OSPAM...@hotmail.comMAPSO_N_> wrote in
message news:QPxJb.112395$AG4.5...@phobos.telenet-ops.be...
I cannt post the code in understandable format, but can tell the
architecture which might help u to understand the problem.
I have 6 applications using the same DLL which is actually just a wrapper
around ODBC classes. I have two MS Access databases. All the applications
create the instance of the recordset only once and then open and close the
recordsets for each iteration. 8000 iteration mean all the applications open
and close the related tables 8000 times. So 8000 runs mean 80, 000 or more
open and close of different tables. When the application crashes, it crashes
on the same table which has only one record and I just read that record from
two of my applications. When it tries to open the recordset it generates an
exception "Memory Allocation Failure" in CRecordset::Open method. One thing
more that this is not exactly 8000, it ranges from 7500 to 8500 iterations.

Hope this clear the problem a bit, more questions are welcome
Thanks
Regards


0 new messages