订单号创建并发问题

 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谢谢指正。

时间: 2024-08-09 06:34:28

订单号创建并发问题的相关文章

生成唯一订单号 (支持每秒1000个并发)

#region 订单号生成(支持每秒1000个并发) private static object locker = new object(); private static int sn = 0; public static string GetOrderNO() { lock (locker) { if (sn == 999) sn = 0; else sn++; return DateTime.Now.ToString("yyMMddHHmmssfff") + sn.ToStrin

分布式系统电商订单号的最佳生成方式

最近在研发区块链支付系统,众所周知,有支付必有订单.今天不做支付系统的具体分析,只来谈谈目前较为热门的订单号码生成方案! 在分布式高并发情况下,订单号必须满足最重要的一个条件:唯一性,订单关系这支付明细,与支付相关的向来都是最重要的,马虎不得. 目前较为成熟的,我所知道的有两种生成方案,接下来做一下对比: 1.根据MySQL自增主键生成订单号 首先,需要创建一张满足自增条件的表,有两个字段即可,id和value,id设置为自增,类型为bigint即可 eg:在mybatis框架中 <insert

分布式系统订单号唯一策略

1.分布式集群架构 2.分布式高并发环境的订单号要求 全局唯一 订单号信息安全要求 趋势递增要求 3.订单号生成策略总结 策略 优点 缺点 格式 uuid 实现简单不占用带宽 无序.不可读.查询慢 32位 db自增 无代码.递归 DB单点故障.扩展有瓶颈 snowflake 不占用带宽.低位趋势递增 依赖服务器时间 18位 redis 无单点故障.性能优于DB递增 占用带宽.Redis集群需要维护 12位 3.1.策略一:UUID(通用唯一识别码) 组成:当前日期+时间+时钟序列+机器识别号(M

订单号生成规则

前阵子,公司有个电子商务项目,需要生成订单号.当时的考虑很简单,取系统时间加上随机数,或者使用 uniqid() 方法.我们都知道,订单号最基本的要求就是唯一,这个条件必须满足.仔细考虑下上述方法,在顾客购买量少的情况下,订单重复的可能性为零,但是在购买高蜂期生成的订单号重复是很有可能发生的.所以上述方法不可靠,有待强化.在网上找了一番,发现这位同学的想法挺不错的,redtamo,具体的请稳步过去看看,我作简要概述,该方法用上了英文字母.年月日.Unix 时间戳和微秒数.随机数,重复的可能性大大

Thinkphp 生成订单号小案例

Thinkphp 生成订单号小案例小伙伴们在日常的商城项目开发中,都会遇到订单号生成的问题,今天呢思梦PHP就带领大家去解读一下生成订单号的问题!首先,订单号我们要明确它有有3个性质:1.唯一性 2.不可推测性 3.效率性,唯一性和不可推测性不用说了,效率性是指不能频繁的去数据库查询以避免重复.况且满足这些条件的同时订单号还要足够的短.不知道小伙伴们在日常的项目中是否也和我一样去思考过生成订单的一些小问题,可能你也会说,这些东西不用想的那么复杂,其实呢,小编也是同意大家的看法,但是殊不知我们做程

生成订单号

生成订单号,最大的问题是要考虑高并发的时候.在网上找的一些方案往往在这种情况下难以适用,比如,查询订单序列最大数,根据系统时间生成等. 再考虑另一种可行的方案:数据库递增序列,没错,确实能解决高并发的问题,但在集群等情况下对数据库压力比较大,而且有些数据库对递增序列没有很好的支持,同时递增序列的位数是一直增加的,也有可能会超出数据库表字段限制. 最好的方案是用java的uuid工具类生成唯一的字符串,然后再取这个字符串对象的hashcode值,因为字符串的值是唯一的,它的hashcode也是唯一

不重复订单号生成规则

偶尔在网上看到的,相对比较好的c#端订单号生成规则 public class BillNumberBuilder{ private static object locker = new object(); private static int sn = 0; public static string NextBillNumber(){ lock(locker){ if(sn == 9999999999) sn = 0; else sn++; return DateTime.Now.ToStrin

C#:lock锁与订单号(或交易号)的生成

1.新建项目(控制台应用程序) 2.新建一个类:OrderIdHelper.cs 1 /// <summary> 2 /// 订单助手 3 /// </summary> 4 class OrderIdHelper 5 { 6 private static readonly object Locker = new object(); 7 private static string _tempId = ""; 8 9 /// <summary> 10 /

订单号唯一的一种解决方案

目前,比较火的nosql数据库,如MongoDB,Redis,Riak都提供了类似incr原子行操作. 下面是PHP版的一种实现方式: 1 <?php 2 /** 3 * 基于Redis的全局订单号id 4 * 5 * @author liujingyu 6 * @copyright liujingyu, 11 八月, 2014 7 **/ 8 9 class OrdersnumAction { 10 11 private $_r; 12 private $_host; 13 private $