using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Sog.Data { /// /// 需要保存数据库的数据基础类,采用数据序列号保证数据保存成功 /// public class DataSeqSave { /// /// 数据版本 /// public uint DataSeq { get; private set; } /// /// 成功保存数据库的版本 /// public uint SavedSuccessSeq { get; set; } /// /// 最后一次发送保存请求的时间 /// public long LastSaveDBReqTime { get; private set; } /// /// 最后一次发送保存请求的数据版本 /// public uint LastSaveDBReqDataSeq { get; private set; } /// /// 数据频繁变化的的时候2此保存请求最小时间间隔 /// public int SaveReqMinInterval { get; set; } = 5000; /// /// 发送请求后,等待db响应的超时时间,毫秒 /// public int SaveReqWaitAckTimeout { get; set; } = 180000; /// /// 是否数据脏,脏了需要保存 /// /// public bool IsDirty() { return SavedSuccessSeq != DataSeq; } /// /// 现在可不可以执行保存操作,如果已经发送了当前数据的保存请求,则需要等待WaitSaveReqTimeout,这个不能太短,否则容易造成mysql雪崩 /// 如果发送请求后数据马上又有变化,那至少也得等待个5秒钟,太频繁了也没必要 /// /// /// public bool CanDoSaveReqNow(long nowMs) { if(!IsDirty()) { return false; } if(LastSaveDBReqDataSeq == DataSeq) { if (nowMs - LastSaveDBReqTime < SaveReqWaitAckTimeout) { return false; } } else { if (nowMs - LastSaveDBReqTime < SaveReqMinInterval) { return false; } } return true; } /// /// 数据置脏,DataSeq++ /// /// public uint MakeDirty() { DataSeq++; return DataSeq; } /// /// 发送保存请求的时候调用,设置一下保存时间 /// /// public void OnSaveReq(long nowMs) { LastSaveDBReqTime = nowMs; LastSaveDBReqDataSeq = DataSeq; } // 设置数据序列号 public void SetDataSeq(uint seq) { DataSeq = seq; } } }