getGeneratedKeys returns 一个空的结果集
getGeneratedKeys returns an empty ResultSet
一句话:Statement.getGeneratedKeys()
偶尔会返回一个空的 ResultSet
,我正在尝试找出原因。
背景:我正在跟踪用户关于订单和他们的一些物品的请求。我有两个表,称它们为 Header
和 Detail
。为了 link header 和详细信息正确,Header
有一个名为 request_id
的 SERIAL
列,我在将行插入 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 数据库交谈
我将这个问题发布到 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.
这似乎对他有用。
一句话:Statement.getGeneratedKeys()
偶尔会返回一个空的 ResultSet
,我正在尝试找出原因。
背景:我正在跟踪用户关于订单和他们的一些物品的请求。我有两个表,称它们为 Header
和 Detail
。为了 link header 和详细信息正确,Header
有一个名为 request_id
的 SERIAL
列,我在将行插入 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 数据库交谈我将这个问题发布到 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.
这似乎对他有用。