在并发数据连接超时问题

最近遇到一个高并发的问题,当初的需求优惠券券号是按照 日期 DateTime.Now.ToString("yyyyMMddHHmmss")  + 最大订单号+1 的方式去新增券号的。

由于业务里面还涉及到多张表操作,用了事务。

第一版上线:  发现 很多订单号重复,找到原因是因为 在并发量高的时候,从数据库获取最大订单号时会产生并发,最新的单号没有新增到数据库,另一个线程已经从数据库查询到最大订单号,这样两个订单号 就是相同的。

为了解决这个问题 ,于是,第二个版本产生。

第二版上线:在获取单号到 新增数据库这段代码加入了锁。

代码如下:

private static object objlock = new object();

lock (objlock)
         {   主体代码     }

这样跟踪了一天,发现不会产生重复的订单号 ,但是过了几天发现另外一个更加严重的问题:一旦并发量达到一定量的时候,这个方法就越来越慢,从最开始的10几毫秒,慢慢到几百毫秒,然后要十几秒,一百秒,然后服务就直接挂了。并且会影响到其他负载均衡到的几台服务器都挂掉。

 通过日志跟代码的分析,发现 在新增券的代码里面原先用到了事务。然后在事务里面又新增了锁。这是一个矛盾的地方,这样直接导致代码性能下降的很快。为了解决这个问题,于是再次修改代码

第三版上线:

  1:为了解决线程池超时问题,必须立刻把锁解除,于是把锁的那段代码注释。

  2:为了解决券号重复的问题,使用随机数来算,字符串+ DateTime.Now.ToString("yyyyMMddHHmmss")+随机数

注意随机数的获取方式,正常清空大家都会直接: 

Random rad = new Random();//实例化随机数产生器rad;
 int value = rad.Next(1000, 10000);//用rad生成大于等于1000,小于等于9999的随机数;

这样获取随机数,但是随机数获取机制是:

在.NET中,随机数一般是用Random来获取,但是当在多任务的并行化编程时,问题就出现了。因为Random是基于时间作为种子来生成伪随机数的,而如果程序在多核并行时,在同一时间内的多个核中取到的时间是一样的,这样一来,生成的伪随机数就有可能会有一样的。如果业务需求中需要不可重复的随机数,那么这后果将会相当严重
 所以不能直接用以上代码获取 随机数。

所以必须采取一种新的方式来获取线程安全的伪随机数。

于是用  RNGCryptoServiceProvider的加密随机生成器,再用其中的强随机序列的方法GetBytes来实现随机。

代码如下:   调用 GetRandomNumber方法 ,参数是随机数的长度,需要几位数 参数就是多少。

 public static string GetRandomNumber(int length)
        {
            string strPwd = string.Empty;
            Random rd = new Random(GetRandomSeed());
            for (int i = 0; i < length; i++)
            {
                strPwd += rd.Next(10).ToString();
            }

            return strPwd;
        }


        public static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }
 

总结:这样修改后,后面就不会再出现重复的优惠券单号。  并且原先高峰期的要几秒,几十秒的时间 回落到 100毫秒以内。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值