条件:
1.流水号规则是配置的,需要先从数据库表里读取配置(有可能包含前缀、时间、流水号)
2.表结构是主表是编码 副表: 编码Id, 类型(前缀、时间、流水号),值(WX、yyyyMMdd、 00001)
public string MakeOddNumber(string code)
{
using (var conn = DapperHelper.GetConn())
{
string oddNumber = string.Empty;
var oddNumberCreate = conn.QueryFirstOrDefault<JcOddNumberCreateTab>($"select * from dbo.JcOddNumberCreateTab where Code = '{code}'");
if (oddNumberCreate == null)
{
return string.Empty;
}
var oddNumberCreateDetails = conn.Query<JcOddNumberCreateDetailTab>($"select * from dbo.JcOddNumberCreateDetailTab where OddCode = '{oddNumberCreate.Id}' order by Sort");
string waterNum = string.Empty;
foreach (var oddNumberCreateDetail in oddNumberCreateDetails)
{
string val = oddNumberCreateDetail.OddFormatValue;
if (oddNumberCreateDetail.OddFormatType == "流水号")
{
int number = 0;
int.TryParse("1" + val, out number);
number++;
waterNum = number.ToString().Substring(1);
oddNumber += waterNum;
}
else if (oddNumberCreateDetail.OddFormatType == "时间")
{
oddNumber += DateTime.Now.ToString(oddNumberCreateDetail.OddFormatValue);
}
else
{
oddNumber += oddNumberCreateDetail.OddFormatValue;
}
}
var trans = conn.BeginTransaction();
try
{
conn.Execute($"update dbo.JcOddNumberCreateDetailTab set OddFormatValue = '{waterNum}' where OddCode = '{oddNumberCreate.Id}' and OddFormatType = '流水号'", null, trans);
conn.Execute($"update dbo.JcOddNumberCreateTab set CurrentOddCode = '{oddNumber}' where Code = '{code}'", null, trans);
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
return "";
}
return oddNumber;
}
}
在多次调用会出现重复
1、redis 桶算法——安排一个进程,定期往桶里放 流水号
2、试试雪花算法(分布式ID神器之雪花算法简介 - 知乎,,Twitter的SnowFlake)
加锁,保证方法是同步执行的,只是性能差点,加事务,保证更新都持久化了