HighTechTalks DotNet Forums  

Cache Dataset object problem

ASP.net Caching microsoft.public.dotnet.framework.aspnet.caching


Discuss Cache Dataset object problem in the ASP.net Caching forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Lefty
 
Posts: n/a

Default Cache Dataset object problem - 07-15-2005 , 09:11 AM






I have an asp.net web app that is coded to use caching. The intermittent
error that I see is the following:

=======================
System.Data.DuplicateNameException: A DataTable named 'REG_EmailOptions'
already belongs to this DataSet.
at System.Data.DataTableCollection.RegisterName(Strin g name)
at System.Data.DataTableCollection.BaseAdd(DataTable table)
at System.Data.DataTableCollection.Add(DataTable table)
=======================

The fact that it is intermittent makes me think the caching is working, and
the error only occurs whenever the objects need to be re-cached. I've
implemented the use of the cache in other areas of the site, but this is the
only one that is throwing an exception. This problem also cannot be
reproduced in dev, only in production, in a server farm environment. Perhaps
the load is required to trigger the error. Can anyone see anything
fundamentally wrong with what they see here?

Thanks in advance for thoughts and suggestions.



try
{

dsEmailOptionsAndSubOptions =
(DataSet)HttpContext.Current.Cache["dsEmailOptionsAndSubOptions"];

if (dsEmailOptionsAndSubOptions == null)
{

dsEmailOptions = (DataSet)HttpContext.Current.Cache["dsEmailOptions"];
dsEmailSubOptions = (DataSet)HttpContext.Current.Cache["dsEmailSubOptions"];

if (dsEmailOptions == null || dsEmailSubOptions == null)
{
dsEmailOptions = GetEmailOptions();
dsEmailSubOptions = GetEmailSubOptions();
}

dsEmailOptions.Tables.Add(
dsEmailSubOptions.Tables["REG_EmailOptions"].Copy() );
dsEmailOptions.Relations.Add("SubOptions",dsEmailO ptions.Tables["REG_Emails"].Columns["EmailID"],
dsEmailOptions.Tables["REG_EmailOptions"].Columns["EmailID"]);

dsEmailOptionsAndSubOptions = dsEmailOptions.Copy();

if (bUseCache)
HttpContext.Current.Cache.Insert( "dsEmailOptionsAndSubOptions",
dsEmailOptionsAndSubOptions );
}

return dsEmailOptionsAndSubOptions;

}


Reply With Quote
  #2  
Old   
Alvin Bruney [MVP - ASP.NET]
 
Posts: n/a

Default Re: Cache Dataset object problem - 07-16-2005 , 08:59 AM






is dsemailoptions dataset global? where is that code running? in
global.asax? if both these conditions are true, you will need to protect
access to the dataset by locking it when you update it.

--
Regards,
Alvin Bruney - ASP.NET MVP

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
Now available @ www.lulu.com/owc, Amazon.com etc
"Lefty" <Lefty (AT) discussions (DOT) microsoft.com> wrote

Quote:
I have an asp.net web app that is coded to use caching. The intermittent
error that I see is the following:

=======================
System.Data.DuplicateNameException: A DataTable named 'REG_EmailOptions'
already belongs to this DataSet.
at System.Data.DataTableCollection.RegisterName(Strin g name)
at System.Data.DataTableCollection.BaseAdd(DataTable table)
at System.Data.DataTableCollection.Add(DataTable table)
=======================

The fact that it is intermittent makes me think the caching is working,
and
the error only occurs whenever the objects need to be re-cached. I've
implemented the use of the cache in other areas of the site, but this is
the
only one that is throwing an exception. This problem also cannot be
reproduced in dev, only in production, in a server farm environment.
Perhaps
the load is required to trigger the error. Can anyone see anything
fundamentally wrong with what they see here?

Thanks in advance for thoughts and suggestions.



try
{

dsEmailOptionsAndSubOptions =
(DataSet)HttpContext.Current.Cache["dsEmailOptionsAndSubOptions"];

if (dsEmailOptionsAndSubOptions == null)
{

dsEmailOptions = (DataSet)HttpContext.Current.Cache["dsEmailOptions"];
dsEmailSubOptions =
(DataSet)HttpContext.Current.Cache["dsEmailSubOptions"];

if (dsEmailOptions == null || dsEmailSubOptions == null)
{
dsEmailOptions = GetEmailOptions();
dsEmailSubOptions = GetEmailSubOptions();
}

dsEmailOptions.Tables.Add(
dsEmailSubOptions.Tables["REG_EmailOptions"].Copy() );
dsEmailOptions.Relations.Add("SubOptions",dsEmailO ptions.Tables["REG_Emails"].Columns["EmailID"],
dsEmailOptions.Tables["REG_EmailOptions"].Columns["EmailID"]);

dsEmailOptionsAndSubOptions = dsEmailOptions.Copy();

if (bUseCache)
HttpContext.Current.Cache.Insert( "dsEmailOptionsAndSubOptions",
dsEmailOptionsAndSubOptions );
}

return dsEmailOptionsAndSubOptions;

}




Reply With Quote
  #3  
Old   
Lefty
 
Posts: n/a

Default Re: Cache Dataset object problem - 07-16-2005 , 03:00 PM



I think I have solved my problem.

None of the datasets shown in the code snip are declared globally. But, I
forgot that reference types are passed and returned by reference. The
GetEmailOptions() and GetEmailSubOptions() functions create their respective
dataset objects, add them to the cache, and return them to this code snip.

The first time it runs, all is well, because I have not yet added the
REG_EmailOptions table to the dsEmailOptions dataset. However, once I do
that, the dsEmailOptions dataset object that was cached in GetEmailOptions()
IS ALSO UPDATED to include the REG_EmailOptions table.

The next time this code runs, if I am able to retrieve the dsEmailOptions
dataset from the cache, it ALREADY contains both datatables. Therefore, I
get the described error when I try to add the table a second time.

For some reason, I was under the impression that when I retrieve an object
from the cache, I am retrieving a copy of that object and actions taken on
that object would not be reflected in the object the next time it was
obtained from the cache, unless of course I explicitly added or replaced the
changed object in the cache.

If this is the case, then should I be locking this cache object before I
edit it or use it? What would happen if 2 different HTTP requests arrive at
the same time, and each thread attempts to Add a datatable to an object
retrieved from the cache? They are both working on the same object, not a
copy correct? I assume 1 would succeed and the other would fail with the
error shown above in this thread? Also, can 2 threads obtain and read info
from a dataset retrieved from the cache at the same time, since it is the
same object?

Thoughts are appreciated.


"Alvin Bruney [MVP - ASP.NET]" wrote:

Quote:
is dsemailoptions dataset global? where is that code running? in
global.asax? if both these conditions are true, you will need to protect
access to the dataset by locking it when you update it.

--
Regards,
Alvin Bruney - ASP.NET MVP

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
Now available @ www.lulu.com/owc, Amazon.com etc
"Lefty" <Lefty (AT) discussions (DOT) microsoft.com> wrote in message
news:B5928839-EE7F-4A7F-98A5-0E0549B39B4C (AT) microsoft (DOT) com...
I have an asp.net web app that is coded to use caching. The intermittent
error that I see is the following:

=======================
System.Data.DuplicateNameException: A DataTable named 'REG_EmailOptions'
already belongs to this DataSet.
at System.Data.DataTableCollection.RegisterName(Strin g name)
at System.Data.DataTableCollection.BaseAdd(DataTable table)
at System.Data.DataTableCollection.Add(DataTable table)
=======================

The fact that it is intermittent makes me think the caching is working,
and
the error only occurs whenever the objects need to be re-cached. I've
implemented the use of the cache in other areas of the site, but this is
the
only one that is throwing an exception. This problem also cannot be
reproduced in dev, only in production, in a server farm environment.
Perhaps
the load is required to trigger the error. Can anyone see anything
fundamentally wrong with what they see here?

Thanks in advance for thoughts and suggestions.



try
{

dsEmailOptionsAndSubOptions =
(DataSet)HttpContext.Current.Cache["dsEmailOptionsAndSubOptions"];

if (dsEmailOptionsAndSubOptions == null)
{

dsEmailOptions = (DataSet)HttpContext.Current.Cache["dsEmailOptions"];
dsEmailSubOptions =
(DataSet)HttpContext.Current.Cache["dsEmailSubOptions"];

if (dsEmailOptions == null || dsEmailSubOptions == null)
{
dsEmailOptions = GetEmailOptions();
dsEmailSubOptions = GetEmailSubOptions();
}

dsEmailOptions.Tables.Add(
dsEmailSubOptions.Tables["REG_EmailOptions"].Copy() );
dsEmailOptions.Relations.Add("SubOptions",dsEmailO ptions.Tables["REG_Emails"].Columns["EmailID"],
dsEmailOptions.Tables["REG_EmailOptions"].Columns["EmailID"]);

dsEmailOptionsAndSubOptions = dsEmailOptions.Copy();

if (bUseCache)
HttpContext.Current.Cache.Insert( "dsEmailOptionsAndSubOptions",
dsEmailOptionsAndSubOptions );
}

return dsEmailOptionsAndSubOptions;

}





Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.