首页 新闻 赞助 找找看

netcore中,并发会引起单号重复,请教怎么解决?

0
悬赏园豆:10 [已解决问题] 解决于 2022-06-09 16:48

  公司有一套仓储系统,有多个业务(入库、出库、盘点、采购、批发等),每个业务都有一个单号,这个单号在表中是唯一键,单号的规则是存储在SQLSERVER表中,按日期每天从0001开始生成,比如202206010001这样。

表结构大概是下面这样

业务名   日期 序号
入库 20220601 1
出库 20220601 5
采购 20220601 3
批发 20220601 999

现在系统业务流程是:

 

业务开始 ->

  取单号数据(所有业务的取单号都在一个静态类的静态方法里)

     -> 设置序号+1

     -> 返回单号

 

-> 保存业务数据 。

 

现在出现的问题是,如果客户在同一时间操作同一个业务人数较多,生成的单号就会重复。

我想在取单号数据那个静态方法里面添加lock代码:

private static object _lock=new object();
public static string GetCode(string name,string date){
    lock(_lock){
          //数据库查询到业务+日期的序号
         // 更改序号+1,并保存到数据库
         //返回组合的单号(name + date + 序号)
    }
}    

但是这样写会有一个问题,就是多个业务他会在同一个线程上取单号,这样如果操作不同业务的人数比较多,那么等待时间会很长。

我想请教下,有没有一种解决方案,能够根据 我的业务和日期,来分开lock取单号。就是每个业务一个线程取单号的。 前提是不硬编码分开写不同业务的取单号?

尾随前行的主页 尾随前行 | 初学一级 | 园豆:0
提问于:2022-06-04 23:45

根据业务名加锁了
lock(name){

}

尾随前行 1年前
< >
分享
最佳答案
1

1,试试引入redis的incr,但要考虑Redis会被清,如果incr后结果是1需要和数据库对比下。也可以开个任务定时检查数据库和redis的差距,如果数据库大就调整redis,如果redis大就更新数据库,最好从运维层次禁止清redis。

2.为了减少访问网络请求,单台机器可以多申请一些,比如incr 1000,未来的1000条都属于这个服务所用,但也可能造成浪费。可以加lock,因为无需访问数据库,应该是不太影响性能的。

3.做好压测,对比下速度是否ok

(引入redis的一个重要原因,如果服务部署多份,单个机器是无法保证唯一的,需要依赖分布式缓存.)

收获园豆:4
从此启程 | 菜鸟二级 |园豆:208 | 2022-06-05 05:25
其他回答(3)
0

想太多了,难道每秒的量能超过几十上百万。一台破机器每秒GUID都能生成上百万个。

收获园豆:2
花飘水流兮 | 园豆:13560 (专家六级) | 2022-06-07 10:43
0

简单的:取id的方法加一个业务标识参数。 比如:标识参数是TBS,这个业务对应一个guid的字符串。
lock(guid字符串){****}

更多参考:如何在高并发分布式系统中生成全局唯一Id

收获园豆:2
滴答的雨 | 园豆:3681 (老鸟四级) | 2022-06-07 17:35
0

按业务代码加锁。

收获园豆:2
保镖 | 园豆:759 (小虾三级) | 2022-06-09 08:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册