读写分离实践简单记录 (2)

基于原来的 读写分离实践简单记录 发现有一个问题, 就是数据同步延迟的问题, 一半会延迟800毫秒左右, 目前的改造解决方案是 :

1. 基于线程

记录上一次执行更新操作(包括添加和删除)的时间到线程, 5秒之内的读操作,都从读写库中读取。 发现如果是ajax 请求会有问题。

2. 基于session (目前采用的方案)

记录上一次执行更新操作(包括添加和删除)的时间到Session, 5秒之内的读操作,都从读写库中读取。

3. 基于log(还没有实施)

想法是比较两个库的事务log(sys.dm_hadr_database_replica_states表中的 end_of_log_lsn)是否一致,如果一致说明就是已经同步了 这个方案的问题就是如果主库一直在写, 那么 log就是一直不一致, 那么读库一直不会被命中。

最后上 基于session 方案的 代码:

 /// <summary>
        ///  
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="connectstring"></param>
        /// <param name="isRead">0 unknow, 1 读写, 2 只读,</param>
        /// <returns></returns>
        private static string GetReadConnectstring(string sql, string connectstring, int isRead = 0)
        {
            if (!SqlConnectionString.CheckIsSuportReadonly(connectstring))
            {
                return connectstring;
            }

            bool isquery = false;

            if (isRead == 0)
            {
                isquery = IsSelect(sql);
            }
            if (isRead == 1)
            {
                isquery = false;
            }

            var result = SqlConnectionString.GetReadonlyConnectionstring(connectstring);
            if (isRead == 2)
            {
                return result;
            }
            if (isquery && (DateTime.Now.Subtract(PreExecTime).TotalMilliseconds > DELAY_TIME))
            { 
                //result = ;
            }
            else
            {
                result = connectstring;
            }
            if (!isquery)
            {
                PreExecTime = DateTime.Now;
            } 
            return result;
        }

        private const int DELAY_TIME = 5000;
        // 上一次执行 更新操作的时间
        //private static DateTime _preExecTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
        private const string PREEXECTIME_SESSION_KEY = "PreExecTime";
        /// <summary>
        /// 上一次执行 更新操作的时间
        /// </summary>
        private static DateTime PreExecTime
        {
            get
            {
                if (HttpContext.Current == null  || HttpContext.Current.Session == null)
                {
                    return DateTime.Now;
                }
                else
                {
                    return ConvertHelper.ToDateTime(HttpContext.Current.Session[PREEXECTIME_SESSION_KEY], new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day));
                }
            }
            set
            {
                if (HttpContext.Current != null && HttpContext.Current.Session != null)
                {
                    HttpContext.Current.Session[PREEXECTIME_SESSION_KEY] = value;
                }
            }
        } 

转载于:https://my.oschina.net/tangruixin/blog/719433

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值