我在一个web应用中利用程序来产生唯一编号。但是是从数据库中编号由程序自动增加来产生编号。
例如数据库中数据原来为:
id
=========
1
2
3
=========
现在由程序自动产生应该是4,但是如果有两个以上用户同时要求产生编号,这时就会产生多个唯一编号
为4。我要如何才能实现多个用户之间的同步啊?
例如数据库中数据原来为:
id
=========
1
2
3
=========
现在由程序自动产生应该是4,但是如果有两个以上用户同时要求产生编号,这时就会产生多个唯一编号
为4。我要如何才能实现多个用户之间的同步啊?
解决方案 »
- jsp项目本地正常,放上服务器后出错
- Java 多线程 条件变量
- <logic:iterate>标签读取和处理数据问题
- jsp用windows身份验证怎么写?
- 快崩溃了~数据库连接池问题:Cannot create JDBC driver of class '' for connect URL 'null'
- 新人求助!希望高手来解答
- java.lang.NullPointerException 高手帮忙看看是什么问题..在线等.
- 探讨关于Frame的单独访问的问题!
- 关于json和hibernate延迟加载的问题
- 用poi包读取excel文件中一个cell的数据时,怎样处理cell为空的情况?谢谢!!
- jfreechart画柱状图时如何在添加链接呢?急,在线等
- jsp中的sql疑问??
public synchronized static int getSerialNo(){
i++;
return i;
}
找个主键生成的包,推荐用uuid
取数据库中MAX_ID;
newID = MAX_ID+1;
更新数据库,MAX_ID = newID;
返回newID;
}
如果你用的是oracle,那可以用SEQUENCE
试试这个吧,毫秒级的唯一编号,不过不能顺序编,只能是唯一的~
select 然后update 再insert
如果是多个jvm应用 使用网络单例
如果需要有顺序可以用sequence
此方式的缺点是,a.依赖数据库,b.在数据备份复制时要特别注意,c.很难跨多个数据库,d.一般不能跨表。
二种方式:使用程序产生。又有几种方式,一种就是简单的序列号增长,一种是使用uuid,再一种是用户自定义的特殊格式(譬如多数业务部门都有特别的产品序列号的规格说明)。实现上可用singleton等模式。个人建议使用Apache的jakarta项目中的commons项目中的Id子项目 http://jakarta.apache.org/commons/sandbox/id/ ,包括了绝大多数id产生方式。显然你自己写出来的不太可能比专家写的更好。个人建议,如果是业务主键(可能会暴露给外界的),应采用第二种方式,如果仅仅是系统内部的相互引用所需的key,特别是仅仅作为数据库内部设施而不会暴露给数据层以上的情况,采用第一种方式。
------------------------------------------
public synchronized static int getSerialNo(){
取数据库中MAX_ID;
newID = MAX_ID+1;
更新数据库,MAX_ID = newID;//在这里已经写回数据库了,而此方法是同步的,下一个用户取的时候,已经maxid已经加一了。所以不可能重复,如果你的程序不方便马上加一后写回,可以考虑在程序中保存这个值。每次程序启动后,读取。
返回newID;
}
------------------------------------------
public synchronized static int getSerialNo(){
取数据库中MAX_ID;
newID = MAX_ID+1;
更新数据库,MAX_ID = newID;//在这里已经写回数据库了,而此方法是同步的,下一个用户取的时候,已经maxid已经加一了。所以不可能重复,如果你的程序不方便马上加一后写回,可以考虑在程序中保存这个值。每次程序启动后,读取。
返回newID;
}
System.currentTimeMillis()???你用一个for循环把System.currentTimeMillis()打出来,看看多少个重复的,算算CPU主频,就知道1毫秒相当于多少个CPU时钟周期了.并发时不出问题才怪.
public synchronized static int getSerialNo(){
取数据库中MAX_ID;
newID = MAX_ID+1;
更新数据库,MAX_ID = newID;//在这里已经写回数据库了,而此方法是同步的,下一个用户取的时候,已经maxid已经加一了。所以不可能重复,如果你的程序不方便马上加一后写回,可以考虑在程序中保存这个值。每次程序启动后,读取。
返回newID;
}不过也可以用触发器,因为编号最终是要写入数据库的,before insert的时候,搞个触发器,产生编号,应该万无一失啊
我现在是这样来实现的:利用spring来管理bean并在保存数据库的方法中产生id.
这样可以吗?
取数据库中MAX_ID;
newID = MAX_ID+1;
更新数据库,MAX_ID = newID;//在这里已经写回数据库了,而此方法是同步的,下一个用户取的时候,已经maxid已经加一了。所以不可能重复,如果你的程序不方便马上加一后写回,可以考虑在程序中保存这个值。每次程序启动后,读取。
返回newID;
}支持这个方法,因为我就是用这个方法
newID = MAX_ID+1;
这样的方法,如果有多次的删除操作,这个流水号会变的很大,呵呵,就是不好看
serialVersionUID = 3513826563487354618L