专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 高性能WEB开发

java自各儿实现序列自动增长,高并发时出现重复和超时

发布时间:2010-05-20 14:01:29 文章来源:www.iduyao.cn 采编人员:星星草
java自己实现序列自动增长,高并发时出现重复和超时
本帖最后由 goodlucktomyself 于 2015-05-23 14:52:04 编辑
 具体情况是这样: 通过java和数据库,自己实现序列自动增长。
实现代码大致如下:
   id_table表结构, 主要字段:
       
 
            id_name  varchar2(16);
            id_val  number(16,0);
            id_prefix  varchar2(4);
   

  
    
  //操作DB 
   public synchronized String nextStringValue(String id){
         SqlSession sqlSess = SqlSessionUtil.getSqlSession();
        sqlSess.update("update id_table set id_val = id_val + 1 where id_name="+id);
        Map map = sqlSess.getOne("select id_name, id_prefix, id_val from id_table where id_name="+ id);
        BigDecimal val = (BigDecimal) map.get("id_val");
      //id_val是具体数字,rePack主要是统一返回固定长度的字符串;如:Y0000001, F0000001, T0000001等
        String idValue = rePack(val, map); 
        return idValue;
  }
  
  //公共方法
public class IdHelpTool{
     public static String getNextStringValue(String idName){
          return getXX().nextStringValue(idName);
    }
}


 具体使用者,都是通过类似这种方式:IdHelpTool.getNextStringValue("PAY_LOG");来调用。

问题:
      (1) 当出现并发时, 有时会获取重复的ID;
      (2) 由于服务器做了相关一些设置,有时调用这个方法,好像还会导致超时。

         为了解决问题(1), 考虑过在方法getNextStringValue上,也加上synchronized , 同步关键字过多,会不会更导致超时?
跪求大侠提供个解决问题的大概思路!!!
------解决思路----------------------
1、推荐 https://github.com/adyliu/idcenter
2、可以通过第三方redis来实现。
------解决思路----------------------
你的getXX()返回是同一个对像么, 要是不同线程访问是不是同一对像,你这锁就没用了
------解决思路----------------------
自增流水号用序列不是更省事么?
------解决思路----------------------
可以参考oracle的序列实现机制。。

做一个池子,缓存一定数量的自增ID。。。在请求使用的时候注意同步处理即可。。但有一个缺点,当你的应用多个布署,就会出现你说的有可能会出现重复。。

在数据库端做比较好。
------解决思路----------------------
补充一点。如果单位时间内请求访问大,在数据库做也会遇到性能问题,就好像,你在不停的请求数据库查询。。

又要想高并发,还是在JAVA端+数据库端相结合来实现,。。
------解决思路----------------------
1、出现重复ID,是因为脏读了,并发的时候不加 synchronized  比如会出现问题

2、但是加了 synchronized  ,性能急剧下降了,本身 java 就是多线程的,你把它单线程使用,不是明智的选择,同时,如果分布式部署的时候,加了 synchronized  也无法控制并发

3、调用这个方法,出现超时的情况,说明你的并发已经超过了数据库所能处理的极限,数据库无限等待导致超时

基于上面的分析,建议采用线程池的方案,支付宝的单号就是用的线程池的方案进行的。

数据库 update 不是一次加1,而是一次加几百甚至上千,然后取到的这 1000个序号,放在线程池里慢慢分配即可,能应付任意大的并发,同时保证数据库没任何压力。
------解决思路----------------------
学习了...楼上分析的比较中肯
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: