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

  公司有一套仓储系统,有多个业务(入库、出库、盘点、采购、批发等),每个业务都有一个单号,这个单号在表中是唯一键,单号的规则是存储在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取单号。就是每个业务一个线程取单号的。 前提是不硬编码分开写不同业务的取单号?

回答

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

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

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

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

以上是netcore中,并发会引起单号重复,请教怎么解决?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>