代码之家  ›  专栏  ›  技术社区  ›  Menachem

getGeneratedKeys返回空的ResultSet

  •  1
  • Menachem  · 技术社区  · 9 年前

    一句话: Statement.getGeneratedKeys() 偶尔会返回一个空的 ResultSet ,我在想为什么。

    背景:我一直在跟踪用户关于订单和一些项目的请求。我有两张桌子,叫他们 Header Detail 为了正确链接标题和细节, 收割台 有一个 SERIAL 列已命名 request_id ,在将行插入时使用 细节 。很长一段时间以来(据我所知)这都很好,但最近我注意到 有时 这个 结果集 由返回 getGeneratedKeys() 为空。

    为了澄清,以下是代码(为安全起见删除了标识细节):

    String hdrSql = "insert into Header "
        + "(request_id, order_id, user_id) values (0, ?, ?)";
    String dtlSql = "insert into Detail "
        + "(request_id, order_id, line_no, comment) values (?, ?, ?, ?)";
    PreparedStatement header = null, details = null;
    int rows = 0;
    long orderId = request.getOrderId();    // request is an object parameter
    try {
        header = connection.prepareStatement(hdrSql, Statement.RETURN_GENERATED_KEYS);
        header.setAutoCommit(false);
        header.setLong(1, orderID);
        header.setString(2, request.getUserId());
        rows = header.executeUpdate();
        ResultSet rs = header.getGeneratedKeys();
        if (!rs.next()) {
            log("Could not get next request_id");   // This statement logged.
            return false;                       // But no exception thrown.
        }
        int requestId = rs.getInt("request_id");
    
        details = connection.prepareStatement(dtlSql);
        details.setInt(1, requestId);
        details.setLong(2, orderId);
        for (Item item : request.getItems()) {
            details.setInt(3, item.getLineNumber());
            details.setString(4, item.getComment());
            rows += details.executeUpdate();
        }
        // Should have inserted 1 row for header, plus 1 row for each item
        return rowsInserted == request.getItems().size() + 1;
    } catch (SQLException sqle) {
        log("Database error" + sqle.getMessage());
        throw sqle;
    } finally {
        try {       // Commit or roll back, depending on status:
            if (rows == request.getItems().size() + 1) {
                header.commit();
            } else {
                header.rollback();
                log("Rolled back request");     // This gets logged, too.
            }
            if (header != null) header.close();
            if (details != null) details.close();
        } catch (SQLException sqle) { sqle.printStackTrace(); }
    

    再一次,我工作了一年多,但在同一天,我发现了一些成功,但大部分失败。第二天再次工作,没有一次失败,也没有任何例外。

    我希望有人能帮忙解释。如果有什么不同,我将通过JDBC与Informix数据库进行交谈。

    1 回复  |  直到 9 年前
        1
  •  0
  •   Menachem    9 年前

    我将此问题发布到 IIUG ,并且我在那里得到的响应指向Informix中的一个bug(APAR IC98247),该bug在比我使用的版本晚的版本中修复。

    我现在正在尝试的解决方案,是一位陷入同样困境的朋友推荐的,就是阅读 request_id 从刚通过变量插入的行

    SELECT max(request_id) from Header where order_id = ${orderId} ;
    // Avoid race condition, accidentally reading the last row inserted by
    //  another thread.
    

    这似乎对他有用。