魔兽资料库上线测试期间,有人反应,有时会出错。可是不管我如果测试,都不能让错误重现,实在是郁闷透了。终于在一次修改后,我想让所有页面的缓存都加上,于是用傲游一下子,把开多个页面的时候,发现出错了.可是在本地测试时,还是不出错.后来多测试了几次,才发现,只在多核的机器上会出错(我只测试了几次,不是太确定).到了这里,我也算松了一口气了.真正难解决的问题,往往是无法让它重现在自己面前的问题,它往往会比修改错误更麻烦.
示例代码如下:
DAL层:
public ItemInfo GetItemModel(int _ItemID)
{
ItemInfo model = new ItemInfo();
using (SqlDataReader Dr = TGBUS.DAL.SqlHelper.ExecuteReader(conn, "Proc_Item_GetModel", new SqlParameter("@ItemID", _ItemID)))
{
if (Dr.Read())
{
model = LoadItemInfoFromDataReader(Dr);
}
Dr.Close();
}
return model;
}
BLL层:
private static DAL.Item dal=new DAL.Item();
public ItemInfo GetItemModel(int_ItemID)
{
string cacheKey = string.Format("WOW_BLL_Item_GetItemModel_{0}", _ItemID);
object obj = DataCache.GetCache(cacheKey);
if (obj == null)
{
obj = dal.GetItemModel(_ItemID);
if(obj!=null)DataCache.SetCache(cacheKey, obj, DateTime.Now.AddMinutes(CacheExpriceTime), TimeSpan.Zero);
}
return (ItemInfo)obj;
}
其实这代码看起来是多么的平常啊.可也就是这平常的代码,让我郁闷了N久.其实解决方案,也是极其实简单的,加一个在DAL中加一个互斥锁就行了.修改后的DAL代码如下:
private static object objLock=new Object();
public ItemInfo GetItemModel(int _ItemID)
{
lock(objLock)
{
ItemInfo model = new ItemInfo();
using (SqlDataReader Dr = TGBUS.DAL.SqlHelper.ExecuteReader(conn, "Proc_Item_GetModel", new SqlParameter("@ItemID", _ItemID)))
{
if (Dr.Read())
{
model = LoadItemInfoFromDataReader(Dr);
}
Dr.Close();
}
return model;
}
}
我也算是终于知道lock语句的用处了.虽然我并没有用这种解决方案.:-)