【问题标题】:getGeneratedKeys returns an empty ResultSetgetGeneratedKeys 返回一个空的 ResultSet
【发布时间】:2015-09-08 00:33:17
【问题描述】:

一句话:Statement.getGeneratedKeys() 偶尔会返回一个空的ResultSet,我正试图找出原因。

背景:我正在跟踪用户对订单及其部分商品的请求。我有两张桌子,叫它们HeaderDetail。为了正确链接标题和详细信息,Header 有一个名为request_idSERIAL 列,我在将行插入Detail 时使用它。这已经运行了很长时间(据我所知),但最近我注意到有时getGeneratedKeys() 返回的ResultSet 是空的。

为了澄清,这里是代码(为安全起见删除了识别细节):

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 数据库通信。

【问题讨论】:

    标签: java sql jdbc primary-key informix


    【解决方案1】:

    我将此问题发布到IIUG,我收到的回复指出了 Informix (APAR IC98247) 中的一个错误,该错误已在比我使用的版本更高的版本中得到修复。

    我现在正在尝试的解决方案,由处于同样困境的朋友推荐,是从刚刚插入的行中读取request_id 的变体

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

    这似乎对他有用。

    【讨论】:

      猜你喜欢
      • 2021-02-20
      • 2013-09-03
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      相关资源
      最近更新 更多