getGeneratedKeys returns an empty ResultSet

∥☆過路亽.° 提交于 2019-12-11 05:48:29

问题


In one sentence: Statement.getGeneratedKeys() is occasionally returning an empty ResultSet, and I'm trying to figure out why.

Background: I am keeping track of users' requests regarding orders and some of their items. I have two tables, call them Header and Detail. To link the header and details properly, Header has a SERIAL column named request_id, which I use when inserting rows into Detail. This has been working fine for a long time (as far as I know), but recently I noticed that sometimes, the ResultSet returned by getGeneratedKeys() is empty.

To clarify, here is the code (identifying details removed for security):

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(); }

Again, been working fine for more than a year, but I found - on the same day - some successes but mostly failures. Worked again the next day, with nary a single failure, and no exceptions at all.

I'm hoping someone can help explain. If it makes any difference, I'm talking to an Informix database over JDBC.


回答1:


I posted this question to IIUG, and the response I got there pointed to a bug in Informix (APAR IC98247), fixed in a version later than the one I am using.

The solution I'm trying now, recommended by a friend in the same predicament, is to read the request_id from the row just inserted by variation of

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

This seems to have worked for him.



来源:https://stackoverflow.com/questions/32447602/getgeneratedkeys-returns-an-empty-resultset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!