string as lock key?

  • Thread starter Thread starter Lloyd Dupont
  • Start date Start date
L

Lloyd Dupont

in an ASP.NET page I have some static method which get value for the cache
or, if the cache is empty, query the database, put the value in the cache
and return it.

because ASP.NET is thread intensive I was thinking to lock these method,
using a fine grained lock.
the best lock I was thinking about was the string key in the cache!
however I have one concern, these unique string might be used in other lock,
could they?
could this be a problem ?

here is my code I wonder about:
-----------
public static string LogsByMonthCacheKey(string blogname)
{
return string.Intern(BLOG_KEY + ":LogsByMonth:" + blogname);
}
public static DataTable GetLogsByMonth(string blogname)
{
string ck = LogsByMonthCacheKey(blogname);
lock(ck) // lock with a unique string, is it alright ?
{
DataTable result = (DataTable) GetCache(ck);
if (result != null)
return result;

SqlConnection conn = DBConnectionPool.Get();
try
{
SqlCommand select = conn.CreateCommand();
select.CommandText = "dbo.gb_EntryByMonth";
select.CommandType = CommandType.StoredProcedure;
select.Parameters.Add(new SqlParameter("@blogname",
blogname));

SqlDataAdapter sda = new SqlDataAdapter(select);
result = new DataTable();
sda.Fill(result);
}
finally { DBConnectionPool.Let(conn); }

AddCache(ck, result);
return result;
}
}
 
Instead try to have a static "object" in the class level and lock
that object.

Shankar
11/5/2004 3:28:06 PM
 
I guess my question is why lock at all? If you don't lock, the worse
that'll happen is X request (let's say 25, which is probably more than you'd
ever get) will hit the function at the same time, and most of those will get
a null ack from GetCache(ck) - thus making them hit the database. They'll
then each fill the cache object up with the same key...ok so not the most
efficient, but that's under pretty bad (and unlikely situations)...after
that though, your using the cache and everything is fast.

On the flip side, if you lock, even when things are cached you'll have to
lock all the other threads...so you are turning this great multithread
environment into a sequential system *yawn*. I could understand it if you
had concerns about things actually getting out of synch and causing some
serious problems..but the only side effect I see (And I could be wrong) is
that you might hit the database one or two extra times between the time the
first cache check fails and it puts it in the cache...seems over the top...

Karl
 
Lloyd Dupont said:
in an ASP.NET page I have some static method which get value for the cache
or, if the cache is empty, query the database, put the value in the cache
and return it.

because ASP.NET is thread intensive I was thinking to lock these method,
using a fine grained lock.
the best lock I was thinking about was the string key in the cache!
however I have one concern, these unique string might be used in other
lock, could they?
could this be a problem ?

That will work fine, so long as you intern the strings (like you're doing).
Just remember that AddCache and GetCache need to be thread-safe since
locking on the cache keys does not serialize access to the cache object.

David
 
Hi Lloyd:

I generally avoid locking on stirng types because they are such wierd
beasts, you never know who else might have a reference to the same
string.

Consider:

String s1 = "MyTest";
String s2 = new
StringBuilder().Append("My").Append("Test").ToString();
String s3 = String.Intern(s2);
Console.WriteLine((Object)s2==(Object)s1); // Different references.
Console.WriteLine((Object)s3==(Object)s1); // The same reference.

I'm still debating if you really need a lock here. The worst that
could happen is you might end up with extra database queries if
multiple requests come in and don't find an entry in the cache. Once
the cache is warm you'll then have the overhead of many find grained
locks. The lock is relatively cheap as locks go, but how many of them
might you have?
 
Not 100% on that usage of locking on a interned string. IIRC, the runtime
is free to move around interns so compact space, so it may be possible for
this lock not to work as expected. To be safe, just lock on the
typeof(class) or a static readonly object set in your static constructor.
Also note that interning is slow. Not sure about all you need for your app,
but I may also concider using a hash table for your cache and maybe even
your database.
 
Thanks all!

I was concerning locking on a string and this cncern seems to be shared....
Also I was wondering about the real usefulness lock as you were too...

Well, maybe I just drop the lock then, hey!
Thanks ;)
 
Back
Top