我正在尝试从executeBatch()
交易中检索生成的密钥,但我只获取要添加的最后一个密钥。
这是我的代码:
PreparedStatement ps_insert = conn.prepareStatement(insertQuery, PreparedStatement.RETURN_GENERATED_KEYS);
for (int i = 0 ; i < adding_dates.length ; i++){
ps_insert.setInt(1, Integer.parseInt(consultant_id));
ps_insert.setDate(2, adding_dates[i]);
ps_insert.setInt(3, Integer.parseInt(room_id));
ps_insert.addBatch();
}
ps_insert.executeBatch();
ResultSet rs = ps_insert.getGeneratedKeys(); //<-- Only the last key retrieved
conn.commit();
我做错了什么?
编辑:抱歉没有提到我在嵌入模式下使用H2(http://www.h2database.com/html/main.html)数据库。
答案 0 :(得分:3)
根据H2 jdbc driver javadocs,这是正常行为:
返回包含上次生成的自动增量的结果集 这个连接的关键,如果有的话。如果没有生成密钥 最后一个修改语句,然后返回一个空结果集。 返回的结果集仅包含最后一行的数据。
答案 1 :(得分:1)
您必须迭代ResultSet
才能检索密钥。
PreparedStatement ps_insert = conn.prepareStatement(insertQuery, PreparedStatement.RETURN_GENERATED_KEYS);
for (int i = 0 ; i < adding_dates.length ; i++){
ps_insert.setInt(1, Integer.parseInt(consultant_id));
ps_insert.setDate(2, adding_dates[i]);
ps_insert.setInt(3, Integer.parseInt(room_id));
ps_insert.addBatch();
}
ps_insert.executeBatch();
ResultSet rs = ps_insert.getGeneratedKeys(); //<-- Only the last key retrieved
if (rs.next()) {
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
do {
for (int i = 1; i <= colCount; i++) {
String key = rs.getString(i);
System.out.println("key " + i + "is " + key);
}
}
while (rs.next();)
}
conn.commit();
答案 2 :(得分:1)
这是H2实施的限制。这是issue。
现在使用不带批处理的插入/更新,或通过选择以某种方式查询生成的密钥。
答案 3 :(得分:0)
如果你在两个线程之间共享一个会话/连接,并且其中两个线程试图同时执行语句,那么你可能会看到这种问题。
您可能需要(a)使用连接池或(b)同步对数据库的整个访问。
例如选项(b)
在你的方法前面添加一个synchronize
令牌,使其成为线程安全的
只是一个想法,因为我不知道你完成执行上下文