java H2 1.4.199 database getGeneratedKeys()返回由另一个insert事务生成的键,或者将来的对象被混淆
我正在使用Java1.8和H21.4.199
我有一个insertRecord(DATA_对象)方法,它将单行插入表中,然后返回生成的此行ID。它实例化一个任务对象,并将其逐个提交到SingleThreadExecutorService上,生成的ID从未来的对象中检索。大多数情况下,它工作得很好。但是,有时会出现这样的情况:
- 第10行插入已提交给ExecutorService
- 第11行插入意味着在“已同步”块前面等待提交给ExecutorService
- 第10行由代码插入,未来返回生成的ID=11
- 第11行由代码插入,未来返回生成的ID=11
我没有工作和可复制的例子,因为这是一个非常罕见的情况,但它发生了
没有抛出异常,我也不知道这是怎么发生的
下面是代码示例:
private static final ExecutorService singleExecutor = Executors.newSingleThreadExecutor();
private static String insertRecord(DATA_OBJECT dataObject) {
Future<String> future;
synchronized (singleExecutor) {
future = singleExecutor.submit(new Task(dataObject));
}
try {
return future.get();
} catch (InterruptedException ex) {
Logger.getLogger(CLASS_NAME.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(CLASS_NAME.class.getName()).log(Level.SEVERE, null, ex);
}
}
private class Task implements Callable<String> {
private DATA_OBJECT dataObject;
public Task(DATA_OBJECT dataObject) {
this.dataObject = dataObject;
}
@Override
public String call() {
try {
return execute(dataObject);
} catch (SQLException ex) {
Logger.getLogger(CLASS_NAME.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
private static String execute(DATA_OBJECT dataObject) {
Connection conn = Database.getTransactedConnection();
String lastId = null;
boolean success = false;
try (
PreparedStatement statement =
conn.prepareStatement(
"insert into TABLE (COLUMN_NAMES) values (VALUES)",
Statement.RETURN_GENERATED_KEYS
)
) {
statement.setString(1, dataObject.STRING_1);
statement.setString(N, dataObject.STRING_N);
success = statement.executeUpdate() == 1;
if (success) {
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
lastID = generatedKeys.getString(1);
}
}
}
} finally {
if (success)
conn.commit();
else
conn.rollback();
Database.releaseConnection(conn);
}
return lastId;
}
我试图找到一种方法来避免100%的这些事件,因为后果是毁灭性的。我该怎么做
导致将来返回标识符的问题可能是什么
共 (0) 个答案