C
Cory
Hi all,
Our issue is a little complex. Our system is an update from a legacy system
that had our clients host their own databases and software. We are now
completely ASP.net based, but have each of our clients data in their own SQL
Server 2005 databases. Currently we have about 150 clients migrated and
therefore 150 DB's.
Each of our clients has a client id and all of users are related to a
client. So, when a user logs in, we know which client they belong to. That
client ID is then used to to point to the correct database for all future
requests. A table in an common database stores the relation between the
client id and the connection string that points to the clients database.
Now, instead of making a call to the DB to retrieve the connection for every
call required by the user, we cache the connectionstring using the
Microsoft.Practices.EnterpriseLibrary.Caching block. Which, has
seemed to work well. Recently though, as the load on the servers increases,
data from someone elses database is making it to the user. I am not sure
why, as everything in the code looks good. I am including a sample.
We have a base object that all our business objects inherit from. The
constructor requires the client id to be passed in when the object is created
and is stored as a module level variable. None of our classes are static.
A new one must always be instantiated with the client id passed in.
private long mClientID = 0;
public BaseProvider(long lClientID)
{
mClientID = lClientID;
}
It also has a method that looks for the clients connectionstring in the
cache. If it is not in the cache, it retrieves the value from the DB and
puts it in the cache.
protected string GetClientConnectionString()
{
CacheManager cache =
CacheFactory.GetCacheManager("ConnectionCache");
string strClientDB;
if (!cache.Contains(mClientID.ToString()))
{
ApplicationPathsDAL.ApplicationPaths.ApplicationPathsDataTable appPathsDT;
ApplicationPathsDAL.ApplicationPaths.ApplicationPathsRow
appPathsRow;
appPathsDT =
ApplicationPathsBLL.ApplicationPathsProvider.Adapter.GetDataByAppClientPathType(Convert.ToInt64(ConfigurationManager.AppSettings["ApplicationID"]),
mClientID, ConfigurationManager.AppSettings["DBPathName"]);
if (appPathsDT.Rows.Count == 0)
{
throw new ApplicationException(Messages.ER_NO_CONNECTION);
}
else
{
appPathsRow =
(ApplicationPathsDAL.ApplicationPaths.ApplicationPathsRow)appPathsDT.Rows[0];
}
strClientDB = appPathsRow.apa_path;
if (string.IsNullOrEmpty(strClientDB))
throw new ApplicationException(Messages.ER_NO_DB);
cache.Add(mClientID.ToString(), strClientDB);
}
else
{
strClientDB = cache[mClientID.ToString()].ToString();
}
return strClientDB;
}
This method just creates the connection.
protected System.Data.SqlClient.SqlConnection GetClientConnection()
{
//long lClientID;
string strClientDB;
System.Data.SqlClient.SqlConnection connection;
if (mClientID > 0)
{
strClientDB = GetClientConnectionString();
connection = new
System.Data.SqlClient.SqlConnection(strClientDB);
}
else
{
throw new ApplicationException(Messages.ER_MISSING_CLIENT);
}
return connection;
}
This is what one of methods look like that will get data for the request.
public ContactDAL.Contact.ConInfoDataTable GetAllConInfo(string sRelPkList)
{
using (ContactDAL.ContactTableAdapters.ConInfoTableAdapter
ConInfoAdapter = new ContactDAL.ContactTableAdapters.ConInfoTableAdapter())
{
ConInfoAdapter.Connection = GetClientConnection();
return ConInfoAdapter.GetAll(sRelPkList);
}
}
We are leaning to this being an issue with the cache as we do not see the
same issues when it is taken out and we make a call to the DB for the
connectionstring on every request. But, this is, of course, not a good
solution as it doubles the number of calls we need to make in order to get
the data. We are not able to replicate this issue in a test environment as
we are unable to create the same type of load, and therefore are unable to
call directly to support. This is a major issue for us.
We are using .Net Framework 2.0. Any help would be greatly appreciated.
Please let me know if there is any other information I can provide that would
help deduce the problem.
Thanks,
Cory
Our issue is a little complex. Our system is an update from a legacy system
that had our clients host their own databases and software. We are now
completely ASP.net based, but have each of our clients data in their own SQL
Server 2005 databases. Currently we have about 150 clients migrated and
therefore 150 DB's.
Each of our clients has a client id and all of users are related to a
client. So, when a user logs in, we know which client they belong to. That
client ID is then used to to point to the correct database for all future
requests. A table in an common database stores the relation between the
client id and the connection string that points to the clients database.
Now, instead of making a call to the DB to retrieve the connection for every
call required by the user, we cache the connectionstring using the
Microsoft.Practices.EnterpriseLibrary.Caching block. Which, has
seemed to work well. Recently though, as the load on the servers increases,
data from someone elses database is making it to the user. I am not sure
why, as everything in the code looks good. I am including a sample.
We have a base object that all our business objects inherit from. The
constructor requires the client id to be passed in when the object is created
and is stored as a module level variable. None of our classes are static.
A new one must always be instantiated with the client id passed in.
private long mClientID = 0;
public BaseProvider(long lClientID)
{
mClientID = lClientID;
}
It also has a method that looks for the clients connectionstring in the
cache. If it is not in the cache, it retrieves the value from the DB and
puts it in the cache.
protected string GetClientConnectionString()
{
CacheManager cache =
CacheFactory.GetCacheManager("ConnectionCache");
string strClientDB;
if (!cache.Contains(mClientID.ToString()))
{
ApplicationPathsDAL.ApplicationPaths.ApplicationPathsDataTable appPathsDT;
ApplicationPathsDAL.ApplicationPaths.ApplicationPathsRow
appPathsRow;
appPathsDT =
ApplicationPathsBLL.ApplicationPathsProvider.Adapter.GetDataByAppClientPathType(Convert.ToInt64(ConfigurationManager.AppSettings["ApplicationID"]),
mClientID, ConfigurationManager.AppSettings["DBPathName"]);
if (appPathsDT.Rows.Count == 0)
{
throw new ApplicationException(Messages.ER_NO_CONNECTION);
}
else
{
appPathsRow =
(ApplicationPathsDAL.ApplicationPaths.ApplicationPathsRow)appPathsDT.Rows[0];
}
strClientDB = appPathsRow.apa_path;
if (string.IsNullOrEmpty(strClientDB))
throw new ApplicationException(Messages.ER_NO_DB);
cache.Add(mClientID.ToString(), strClientDB);
}
else
{
strClientDB = cache[mClientID.ToString()].ToString();
}
return strClientDB;
}
This method just creates the connection.
protected System.Data.SqlClient.SqlConnection GetClientConnection()
{
//long lClientID;
string strClientDB;
System.Data.SqlClient.SqlConnection connection;
if (mClientID > 0)
{
strClientDB = GetClientConnectionString();
connection = new
System.Data.SqlClient.SqlConnection(strClientDB);
}
else
{
throw new ApplicationException(Messages.ER_MISSING_CLIENT);
}
return connection;
}
This is what one of methods look like that will get data for the request.
public ContactDAL.Contact.ConInfoDataTable GetAllConInfo(string sRelPkList)
{
using (ContactDAL.ContactTableAdapters.ConInfoTableAdapter
ConInfoAdapter = new ContactDAL.ContactTableAdapters.ConInfoTableAdapter())
{
ConInfoAdapter.Connection = GetClientConnection();
return ConInfoAdapter.GetAll(sRelPkList);
}
}
We are leaning to this being an issue with the cache as we do not see the
same issues when it is taken out and we make a call to the DB for the
connectionstring on every request. But, this is, of course, not a good
solution as it doubles the number of calls we need to make in order to get
the data. We are not able to replicate this issue in a test environment as
we are unable to create the same type of load, and therefore are unable to
call directly to support. This is a major issue for us.
We are using .Net Framework 2.0. Any help would be greatly appreciated.
Please let me know if there is any other information I can provide that would
help deduce the problem.
Thanks,
Cory