我的应用程序使用 Java + jOOQ + H2DB。我创建了两个Threads
继续执行。
线程一:连续往表A中插入记录
线程 2:从表 A 中选择 10000 条连续记录的限制
当我运行我的应用程序时,有时会org.h2.jdbc.JdbcSQLSyntaxErrorException
抛出,SQL 语句已被某些字符更改 PUBLIC.SCENAR ऀ☀䙉O_EXECUTE_LOG
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "PUBLIC.SCENAR ऀ☀䙉O_EXECUTE_LOG.TOTAL_RUNNING_TIME" not found; SQL statement:
select "PUBLIC"."SCENARIO_EXECUTE_LOG"."LOG_SEQ", "PUBLIC"."SCENARIO_EXECUTE_LOG"."USER_ID", "PUBLIC"."SCENARIO_EXECUTE_LOG"."EXECUTE_DIV", "PUBLIC"."SCENARIO_EXECUTE_LOG"."EXECUTE_SCENARIO_ID", "PUBLIC"."SCENARIO_EXECUTE_LOG"."EXECUTE_START_TIME_UTC", "PUBLIC"."SCENARIO_EXECUTE_LOG"."EXECUTE_END_TIME_UTC", "PUBLIC"."SCENARIO_EXECUTE_LOG"."EXECUTE_START_TIME_LOCAL", "PUBLIC"."SCENARIO_EXECUTE_LOG"."EXECUTE_END_TIME_LOCAL", "PUBLIC"."SCENAR ऀ☀䙉O_EXECUTE_LOG"."TOTAL_RUNNING_TIME", "PUBLIC"."SCENARIO_EXECUTE_LOG"."LOG_FOLDER_NAME", "PUBLIC"."SCENARIO_EXECUTE_LOG"."RESULT_DIV" from "PUBLIC"."SCENARIO_EXECUTE_LOG" where "PUBLIC"."SCENARIO_EXECUTE_LOG"."LOG_SEQ" = cast(? as int) for [42122-199]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:451)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
at org.h2.message.DbException.get(DbException.java:205)
at org.h2.message.DbException.get(DbException.java:181)
at org.h2.expression.ExpressionColumn.getColumnException(ExpressionColumn.java:176)
at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:158)
at org.h2.command.dml.Select.prepare(Select.java:1245)
at org.h2.command.Parser.prepareCommand(Parser.java:689)
at org.h2.engine.Session.prepareLocal(Session.java:627)
at org.h2.server.TcpServerThread.process(TcpServerThread.java:270)
at org.h2.server.TcpServerThread.run(TcpServerThread.java:175)
at java.base/java.lang.Thread.run(Thread.java:844)
相反,它是PUBLIC.SCENARIO_EXECUTE_LOG
如果我只运行线程 1 或线程 2,则不会出现此错误
这个错误是从哪里出现的?
更新:
助手类
private static Connection h2Connection;
private static DSLContext dslContext;
private static Server server;
public static DSLContext getDSLContext() throws Exception {
if (dslContext == null) {
dslContext = new DefaultDSLContext(getConnection(), SQLDialect.H2, settings);
}
return dslContext;
}
private static Connection getConnection() throws Exception {
if (h2Connection == null) {
Class.forName("org.h2.Driver");
String url = String.format("jdbc:h2:tcp://localhost/%s;", (DB_PATH.isEmpty() ? OUTPUT_PATH + folderPath + H2DB_PATH : DB_PATH)) +
String.format("USER=%s;", USER_NAME) +
String.format("PASSWORD=%s;", PASSWORD);
System.setProperty("java.net.useSystemProxies", "false");
server = Server.createTcpServer("-tcpAllowOthers").start();
System.setProperty("java.net.useSystemProxies", "true");
try {
h2Connection = new JdbcConnection(url, new Properties());
return h2Connection;
} catch (Exception ex) {
log.error("Error fetching connection", ex);
throw ex;
}
}
return h2Connection;
}
主班
Thread insertExecuteLog = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
Random random = new Random();
scenarioExecuteLogRecordInsert.setLogSeq(random.nextInt(10000000 - 4000000) + 4000000);
JooqScenarioExecuteLogHelper.insertExecuteLog(scenarioExecuteLogRecordInsert);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
});
Thread getExecuteLog = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
ScenarioExecuteLogRecord[] listScenarioExecuteLog2 = JooqScenarioExecuteLogHelper.getListScenarioExecuteLog();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
});
insertExecuteLog.start();
getExecuteLog.start();
SQL
public static ScenarioExecuteLogRecord[] getListScenarioExecuteLog(){
DSLContext dslContext = JooqRpaSysDBHelper.getDSLContext();
return dslContext.selectFrom(SCENARIO_EXECUTE_LOG)
.orderBy(SCENARIO_EXECUTE_LOG.LOG_SEQ)
.limit(10000)
.fetchArray();
}
public static void insertExecuteLog(ScenarioExecuteLogRecord scenarioExecuteLogRecord){
DSLContext dslContext = JooqRpaSysDBHelper.getDSLContext();
dslContext.insertInto(SCENARIO_EXECUTE_LOG)
.set(SCENARIO_EXECUTE_LOG.LOG_SEQ, scenarioExecuteLogRecord.getLogSeq())
.set(SCENARIO_EXECUTE_LOG.USER_ID, scenarioExecuteLogRecord.getUserId())
.set(SCENARIO_EXECUTE_LOG.EXECUTE_DIV, scenarioExecuteLogRecord.getExecuteDiv())
.execute();
}