有个方法已经同步了,该方法先产生一个key,首先查询数据库中是否有这个key的记录,如果有更新相应记录,如果没有插入一条记录。(key在数据库中不可以重复,有约束条件)在集群环境下做压力测试,出现了违反唯一性约束的异常(就是上面key值不可以重复的约束),
请问解决方法

解决方案 »

  1.   

    public synchronized Long generateBizNum(final String key) throws ServiceException {
    Long value = null;
    long mid_value;
    TbBizBO bo = new TbBizBO();
    bo.setId(key);

    try {
    bo = (TbBizBO) dataMgr.selectByPK(bo);

    if (bo != null) {
    value =  bo.getNum();
    mid_value = value.longValue() + 1;
    bo.setNum(new Long(mid_value));
    dataMgr.update(bo);
    dataMgr.flush();
    } else {
    bo = new TbBizBO();
    bo.setId(key);
    bo.setNum(new Long(2));
    value = new Long(1);
    dataMgr.insert(bo);
    dataMgr.flush();
    } } catch (DAOException e) {
    throw new ServiceException("产生编号异常!",e);
    }
    return value;
    }
      

  2.   

    这里的dataMgr是实现hibernate数据库操作的管理类
      

  3.   

    好像与java侧的程序没有关系
    问题出在db侧
    从程序看是首先取得TbBizBO对应的表的最大id值
    如果有的话,更新,负责max+1插入
    但是
    bo = (TbBizBO) dataMgr.selectByPK(bo);
    似乎没有锁表
    所以另外一个查询得到了同样的max
    然后加1
    所以出现违反约束不知道方法的参数key是咋得到的
    最好用一个sequense
    那么就没有必要担心问题了
      

  4.   

    bo = (TbBizBO) dataMgr.selectByPK(bo);
    这个方法的代码呢。也贴出来看看
      

  5.   


    思路是对的,怎么会重复key。难道有人手动插入了。
    如果程序没有问题是不会重复的,你可以在出现异常的时候
    try {} catch(报重复key的异常) {
         在这里把那个key重新生成下,如果再重复继续生成(递归);前台生成key的代码没有逻辑业务问题
    }
      

  6.   

    在集群的情况下,是可能的,而且出现了违反唯一性约束的异常,是数据库抛的,抛的是ERRO,好像不是exception