我现在做的程序里有一个表,是用时间做主键的插入数据的时候用SELECT SYSTIMESTAMP FROM DUAL获取数据库时间我在程序里有一段代码连续执行了两次插入操作在服务器压力大的时候没什么问题但是在服务器压力小的时候,两次插入操作获取的时间是相同的,造成了主键冲突主键冲突是程序抛出异常得到的结果之所以认为时间相同是这个问题的原因是我用debug模式跟踪短点的时候就不会出现执行代码的时候偶尔会出现这个问题我现在的做法是在获取时间的时候让线程sleep 5毫秒但这做法太土鳖了,技术评审的时候绝对被骂的狗血喷头所以来问问大家有什么好的方法没有不知道有没有高手能告诉我怎么在Oracle里获取一个绝对不重复的时间戳谢谢大家

解决方案 »

  1.   

    你debug的时候因为程序运行不是连续的
    所以你会出现那种情况的数据量大的时候对数据库的压力才是你时间主键成立的条件你采用数据库加入系统时间的方案来解决而不行
    因为你只处理一两条数据
    时间太短造成的不过你可以对数据库的主键做一下hibernate的映射
    手动加入的方式
    使用System.gettimeMillion()作为你的主键插入
    在后台的代码中使用
    就不会造成数据库的主键冲突了可能函数写的不是很正确
    你可以使用MyEclipse的自动补齐功能来完成
    我手头没有工具
    只能凭着记忆给你写了
    祝你成功
      

  2.   

    systimestamp在不同平台返回的精度都不一样,依赖操作系统。windows机器重复的可能性很大。本来这个东西就不适合用来做唯一主键,一定要用,只能捕获特定的主键冲突错误:
    ORA-00001: unique constraint violated
    然后换个姿势,再来一次。
      

  3.   

    1. set pk;Date date--first ItemDate date2=date.addMill(0001)//no such method in api,so you must get one!insert(date);
    insert(date2);
    --------------------------------------------------------------------------------
    2.two transactions 
    you can use two different transactions to insert data.
      

  4.   

    当初设计这个表的时候我就怀疑过时间做主键到底可行不可行但是意见没有被领导采纳刚才和DBA交流过,DBA说这设计实在太XX了汗一个
      

  5.   

    楼主,您好,真是太巧合了,我们也是用一个时间做主键。也是用到DUAL。我们处理方法如下:
    select LPAD(OPERATION_SEQ.NEXTVAL,30,0) from dual
    结果是:产生一个30位的数字字符串,这个字符串完全是根据时间生成的,绝对不会重复,这个您放心。
    结果如:000000000000000000000000434026、000000000000000000000000434027、……
    我们的方法是这样的:
    public static String creaeTimeKey() throws Exception {

    String returnStr = "";
    DBManager db = DbFactory.db3;
    conn=db.conn;
    Statement stmt = conn.createStatement();
    ResultSet rs = null;
    //conn.setAutoCommit(false);
    StringBuffer sql = new StringBuffer("");
    sql.append("select LPAD(OPERATION_SEQ.NEXTVAL,30,0) from dual");
    rs = stmt.executeQuery(sql.toString());
    if (rs.next()) {
    returnStr = rs.getString(1);
    }
    //conn.commit();
    // 关闭连接
    rs.close();
    stmt.close();
    return returnStr;
    }
    希望以上对楼主有帮助。
      

  6.   

    当然您也可以设置一个20位的。另外也可以用UUID产生主键,代码如下:
    public static String createUUID() {
    return  java.util.UUID.randomUUID().toString();
    }