高并发下如何生成唯一订单号?
1、 使用数据库自增Id优势:编码简单,无需考虑记录唯一标识的问题。
缺陷:1) 在大表做水平分表时,就不能使用自增Id,因为Insert的记录插入到哪个分表依分表规则判定决定,若是自增Id,各个分表中Id就会重复,在做查询、删除时就会有异常。
2) 在对表进行高并发单记录插入时需要加入事物机制,否则会出现Id重复的问题。
3) 在业务上操作父、子表(即关联表)插入时,需要在插入数据库之前获取max(id)用于标识父表和子表关系,若存在并发获取max(id)的情况,max(id)会同时被别的线程获取到。
4) 等等。
结论:适合小应用,无需分表,没有高并发性能要求。
2、 单独开一个数据库,获取全局唯一的自增序列号或各表的MaxId1) 使用自增序列号表专门一个数据库,生成序列号。
开启事物,每次操作插入时,先将数据插入到序列表并返回自增序列号用于做为唯一Id进行业务数据插入。
注意:需要定期清理序列表的数据以保证获取序列号的效率;插入序列表记录时要开启事物。
使用此方案的问题是:每次的查询序列号是一个性能损耗;如果这个序列号列暴了,那就杯具了,你不知道哪个表使用了哪个序列,所以就必须换另一种唯一Id方式如GUID。
2) 使用MaxId表存储各表的MaxId值专门一个数据库,记录各个表的MaxId值,建一个存储过程来取Id,逻辑大致为:开启事物,对于在表中不存在记录,直接返回一个默认值为1的键值,同时插入该条记录到table_key表中。
而对于已存在的记录,key值直接在原来的key基础上加1更新到MaxId表中并返回key。
使用此方案的问题是:每次的查询MaxId是一个性能损耗;不过不会像自增序列表那么容易列暴掉,因为是摆表进行划分的。