订单号创建并发问题

 
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 
 7 namespace Qxun.Framework.Utility
 8 {
 9     public class CreateOrderNo
10     {
11         /// <summary>
12         /// 订单格式:时间加随机数+线程ID
13         /// 因为像并发或者超快进入或者其他情况,导致订单号一致的时候,根据线程ID比较分得开一些
14         /// </summary>
15         /// <param name="count">随机数个数,默认3个</param>
16         /// <param name="timeFormat">默认时间精确到毫秒</param>
17         /// <returns>订单string</returns>
18         public static string DateTimeAndNumber(int count = 3, string timeFormat = "yyyyMMddHHmmssFFF")
19         {
20             string threadID= Thread.CurrentThread.ManagedThreadId.ToString().PadLeft(4,'0');
21             string time = string.Format("{0:" + timeFormat + "}", DateTime.Now).PadRight(timeFormat.Length,'0');
22             List<int> number = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
23             string numberList = string.Join("", Collection.Random(number, count));
24             return string.Format("{0}{1}{2}", time, numberList,threadID);
25         }
26     }
27 }
创建订单号

因为创建订单号的时候,存在并发、请求过快导致时间在毫秒级以下、其他一些情况,造成datetime.now format的值相同,且由于时间过短,Random随机数很多时候是不会变化的,从而造成订单号一致的情况

解决方式:

1.可以传入个一一对应的ID值

2.使用线程值,在短时间内,线程ID值一般是不会相同的,至于堵塞的情况,这个还没验证过

使用线程值的话,对于方法调用比较方便,不需要传什么参数了

而对于静态方法的使用,有说并发的时候,会出现问题,但是如果静态方法不对静态变量进行调用或者处理的话,一般来说是没有什么影响的。

写了个方法进行并发测试,在进入方法和出方法的时候,线程ID值都是相同的,应该可以证明没有什么影响吧...

 

当然啦,这些验证应该没有那么严谨。内部的机制并不是那么了解,只是以现在能看到的说一下。如有错误,O(∩_∩)O谢谢指正。

原文地址:https://www.cnblogs.com/danlis/p/6401157.html