//向DB中写入一条数据 internal static int SingleSaveItem(int msgId, InnerCacheItem cacheItem, int dataVersion) { if (DataCacheConfig.IsPersistent) { try { DataDML.Save(msgId, cacheItem.Valid, dataVersion, cacheItem.DataMessage); } catch (Exception ex) { DBConn.Close(); LogSys.Log(LOG_TYPE.ERROR, "SingleSaveItem ERROR. MsgId:{0}, Error:{1}\nStacktrace:{2}", msgId, ex.Message, ex.StackTrace); throw ex; } } return(1); }
//在DBThread线程中执行 private void SaveDirtyItemToDB(int msgId, InnerCacheItem cacheItem, string saveCountKey, int saveCount, int dbDataVersion) { try { DataSaveImplement.SingleSaveItem(msgId, cacheItem, dbDataVersion); //写入DB成功 DataCacheSystem.Instance.QueueAction(() => { cacheItem.DirtyState = DirtyState.Saved; }); } catch (Exception e) { //写入DB失败 DataCacheSystem.Instance.QueueAction(() => { cacheItem.DirtyState = DirtyState.Unsaved; }); LogSys.Log(LOG_TYPE.ERROR, "Save to MySQL ERROR:{0}, \nStacktrace:{1}", e.Message, e.StackTrace); } }
//==========================通过QueueAction调用的方法=========================================== //注意!回调函数目前在缓存线程与db线程都可能调用,回调函数的实现需要是线程安全的(目前一般都是发消息,满足此条件)。 internal void Load(Msg_LD_Load msg, PBChannel channel, int handle) { //首先在缓存中查找数据,若未找到,则到DB中查找 bool isLoadCache = true; Msg_DL_LoadResult ret = new Msg_DL_LoadResult(); ret.MsgId = msg.MsgId; ret.PrimaryKeys.AddRange(msg.PrimaryKeys); ret.SerialNo = msg.SerialNo; ret.ErrorNo = 0; for (int i = 0; i < msg.LoadRequests.Count; ++i) { Msg_LD_SingleLoadRequest req = msg.LoadRequests[i]; KeyString loadKey = KeyString.Wrap(req.Keys); switch (req.LoadType) { case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadAll: { isLoadCache = false; } break; case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadSingle: { InnerCacheItem item = m_InnerCacheSystem.Find(req.MsgId, loadKey); if (item != null) { Msg_DL_SingleRowResult result = new Msg_DL_SingleRowResult(); result.MsgId = req.MsgId; result.PrimaryKeys.AddRange(req.Keys); result.DataVersion = 0; //TODO: 这个DataVersion有用吗? result.Data = item.DataMessage; ret.Results.Add(result); } else { isLoadCache = false; } } break; case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadMulti: { List <InnerCacheItem> itemList = m_InnerCacheSystem.FindByForeignKey(req.MsgId, loadKey); foreach (var item in itemList) { Msg_DL_SingleRowResult result = new Msg_DL_SingleRowResult(); result.MsgId = req.MsgId; result.PrimaryKeys.AddRange(req.Keys); result.DataVersion = 0; //TODO: 这个DataVersion有用吗? result.Data = item.DataMessage; ret.Results.Add(result); } } break; } } if (isLoadCache) { channel.Send(ret); LogSys.Log(LOG_TYPE.INFO, "Load data from cache. MsgId:{0}, Key:{1}", msg.MsgId, KeyString.Wrap(msg.PrimaryKeys).ToString()); } else { //查找DB交给DBLoad线程操作 DbThreadManager.Instance.LoadActionQueue.QueueAction(DataLoadImplement.Load, msg, (MyAction <Msg_DL_LoadResult>)((Msg_DL_LoadResult result) => { if (result.ErrorNo == Msg_DL_LoadResult.ErrorNoEnum.Success) { foreach (Msg_DL_SingleRowResult row in result.Results) { m_InnerCacheSystem.AddOrUpdate(row.MsgId, KeyString.Wrap(row.PrimaryKeys), KeyString.Wrap(row.ForeignKeys), row.Data); } } channel.Send(result); LogSys.Log(LOG_TYPE.INFO, "Load data from database. MsgId:{0}, Key:{1}", msg.MsgId, KeyString.Wrap(msg.PrimaryKeys).ToString()); })); } }