工作中常常遇到流水号生成的问题,有的客户要求流水号必须连续,这个我们的开发工作提出了一个小难题。
解决方法如下:
方法一:采用最大号表的形式
在数据库中创建一个表专门存放其他数据库的最大流水号,table_maxOrderID {table1_max,table2_max};
在向数据库中插入数据的时候,首先想table_maxOrderId表查询到当前表的最大号加1,先更新最大号表,然后保存到业务数据。
优点:效率高
缺点:号码浪费大一些(例如保存的时候失败了,那么这个号码就浪费了。)
方法二:采用抢号的形式
这个不需要创建最大号表,在向数据库中保存数据的时候,获取当前表的最大流水号。例如:
select max(ID) from tableName ; 让后将结果加一。
优点:速度快,不浪费号码;
缺点:并发的时候,号码重复造成数据无法保存。
解决办法:抢号。如果保存失败,那么重复抢号例如:
public synchronized String getOrderId(String shengid) {
if (shengid == null || "".equals(shengid.trim())) {
throw new NullPointerException("在获取流水号的时候,省id为空!获取流水号失败!");
}
// 首先查找所在地区查找企业表中有没有数据
int num = xjqyDao.getCountBySql(" and qy_sheng='" + shengid + "'");
String orderId = null;
if (num == 0) {
orderId = "0001";
} else {
//必须找到本省最大的档案的id
String maxDabh = xjqyDao.getMaxDabhBySheng(shengid);
num = Integer.parseInt(maxDabh.substring(6));
String temp = (num + 1) + "";
int LEN = temp.length();
if (LEN > 4) {
log.error("出错了!一个省的蚕茧收购加工企业的个数不能超过1万!");
return null;
}
for (int i = 0; i < 4 - LEN; i++) {
temp = "0" + temp;
}
orderId = temp;
}
return orderId;
}
for (int i = 0; i < 5; i++) { // 连续抢号5次,如果失败,请用户稍后再试!
try {
String orderId = getOrderId(xjqy.getSheng());// 获取连续的流水号
log.debug("获取到的连续的流水号为:" + orderId);
String dabh = ""; // 档案编号
String code = ""; // 企业编号
dabh = xjqy.getSheng() + xjqy.getJdrq().substring(0, 4)
+ orderId;
log.debug("档案编号为:" + dabh);
xjqy.setDabh(dabh);
// 所在省做了js校验
if (xjqy.getShi() == null || xjqy.getShi().equals("")) {
// 如果市为空
code = xjqy.getSheng() + "0000" + xjqy.getLb()
+ orderId;
} else if (xjqy.getXian() == null
|| xjqy.getXian().equals("")) {
// 如果县为空
code = xjqy.getShi() + "00" + xjqy.getLb() + orderId;
} else {
code = xjqy.getXian() + xjqy.getLb() + orderId;
}
log.debug("企业编号为:" + code);
xjqy.setCode(code);
xjqyDao.create(xjqy);
log.debug("create object");
flag = true;// 保存成功!
break; // 退出循环
} catch (Exception e) {
log.debug("保存企业信息出错:", e);
}
}
if (!flag) {
throw new OurException("保存失败!请稍后重试!");
}
小结:
如果要从严格意义上生成连续的流水号,那么应该采用抢号的方法,同时限制用户不准删除记录,这样才能保证流水号的严格连续,否则录入5条,删掉其中的2条,那么用户看到的记录的号码将无法连续了。
分享到:
相关推荐
根据字母生成流水号,例如当前流水号为AA,则生成新的流水号为AB。若当前流水号为AZ,则生成新的流水号为BA。若当前流水号为ZZ,则生成新的流水号为AAA。若当前流水号为空,则根据传入的位数生成初始值,以此类推。
流水号生成软件 生成工具
自动为每一条插入的数据按照自己设定的格式生成流水号
非常好用的日期工具 流水号 日期格式化 获取当前时间戳 转换日期...
java按日期加流水号方式生成订单号,已经测试过,可递增方式生成。
自己写的一点小代码,多有不当,请指正! public string GetAutoDocNo() { string DocNo = "AD"; string today = DateTime.Today.Date.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo);...
存储过程实现流水号,可以实现防止并发生成重复的流水号,.net 技术,sql server 数据库编写,可以参考学习哦
可以生成各种类型的不会重复的流水号,支持批量生成流水号,支持生成各个类型的流水号且互不冲突,例如给每个业务生成互不影响的流水号。 生成的流水号支持各种格式和长度,例如TB201708100001,AAS2017080001,SDB...
这里介绍的是订单号或者流水号的生成,用的方法是时间戳+随机数,如果你要严谨的算法生成的订单号,请勿下载,下载前,可以看下这篇文章介绍【https://blog.csdn.net/qq_27471405/article/details/82887786】
这里的流水号是当前日期+四位数流水号,流水号是按照天流水,既每天第一张单号都是0001
用于自动生成流水账号的存储过程 有详细的注释
按流水号生成编码(脚本)
生成并发唯一性流水号的解决方案 sql c#
abap产生流水号的两种方法 sap中没有序列号,但是可以用范围对象来维护流水号。或者直接从数据库获取。
mysql创建流水号,以前也一直不知道怎么写,最后我知道了,然后我保存了下来
生成相同长度的流水号
/// 根据时间生成流水号 /// 流水号组成如XS200811050001 /// XS:销售 /// 20081105:日期 /// 0001:20081105日的第一个订单 /// /// <returns></returns> private string GetNumberString() { string ...
1、每天都会生成初始值1,且递增的流水号 2、不存在多线程问题
一个获取系统时间然后根据系统时间生成流水号的java程序