前言:最近旅游的主页面处理搜索慢的情况,使用的机制是Redis的GetValue方式进行存储静态变量的方式,出现了Redis的timeout的情况;
解决方法以及思路:使用静态变量字典的方法进行处理
1.定义一个字典,主要是保存栏位比较少,类别、栏位、跳转地址等,一个key、一个实体类;
2.定义一个时间,每次更新字典的时候会保存一下,下次读取的时候会判断是否经过了十分钟,经过了十分钟之后,进行读取一次数据库进行更新字典;
3.进行双重锁的方式进行,避免出现锁穿透的情况
代码:
public static List GetAllTagInfo() { //System.Diagnostics.Debug.WriteLine(""); //缓存过期&&更新动作解放状态 if ((_campaignTagInfoData.RemoteData == null || _campaignTagInfoData.RemoteTime.AddMinutes(10) < DateTime.Now) && !CampaignRemoteData.SignRefresh) {
//System.Diagnostics.Debug.WriteLine(""); bool taskCheckCreate = false; lock (CampaignRemoteData.LockTask) { if (!CampaignRemoteData.SignTask) { CampaignRemoteData.SignRefresh = true;//开始进入异步更新,关闭后续触发的更新通道,规避异步执行期间大量访问造成多线程创建 CampaignRemoteData.SignTask = true;//锁住后续并发入坑 taskCheckCreate = true;//判定当前请求是否需要生产第一个线程 } } //System.Diagnostics.Debug.WriteLine(""); if (taskCheckCreate) { try { Task.Factory.StartNew(() => { try { //System.Diagnostics.Debug.WriteLine(""); List result = null; using (DbContext context = new DbContext(DBOperationType.Read, DbConnection.Db_TcTourismCampaign)) { string strSql = $@" "; result = context.SQLContext.ExecuteQueryModels(strSql, new Tc.Gl.Framework.ORM.Attrbuites.SqlNote("", "查询营销标签信息")); } lock (_campaignTagInfoData) { _campaignTagInfoData.RemoteData = result; _campaignTagInfoData.RemoteTime = DateTime.Now; } } catch (Exception ex) { LogModel.LogRecord("CampaignRemoteDataService", "GetAllCampaignTagInfo", "", ex); } finally { CampaignRemoteData.SignRefresh = false;//异步处理完成,解放下一次的更新动作 CampaignRemoteData.SignTask = false;//解锁第一个线程生产 } }); } catch (Exception ex) { LogModel.LogRecord("CampaignRemoteDataService", "GetAllCampaignTagInfo_1", "", ex); CampaignRemoteData.SignRefresh = false;//异步处理完成,解放下一次的更新动作 CampaignRemoteData.SignTask = false;//解锁第一个线程生产 } } } return _campaignTagInfoData.RemoteData ?? new List(); }
弊端:热门搜索的字典一定是一个比较少的数据库;最好的记录是在1000行以内;