Mysql PreparedStatement查询返回0行,尽管表中有新插入的数据

d7v8vwbk  于 2023-06-04  发布在  Mysql
关注(0)|答案(1)|浏览(182)

我正在移植一个旧的java程序,它每隔几分钟就轮询一次数据库。它只是查询某个表,并根据行值处理它们(我必须维护轮询,不能像debezium那样更改为CDC)。我使用vertx setTimer来进行周期性调度(这样一个在前一个结束后开始)。我在类private static Handler<Long> pollingHandler;中有这个属性,并如下所示初始化它,并第一次调用它。当我复制带有start_idbatch_size的各种有效参数的查询FETCH_SAMPLE_DATA_QUERY并在mysql控制台中使用它时,它可以工作。在代码中,只有第一次调用工作并返回正确的行数,并且在完成处理后,start_id被更新以用于下一个计划的调用。但随后的调度调用都返回0行。在调试时,日志中填充了Processing 0 records。我似乎无法理解为什么它返回一个空的RowSet。当我检查调试日志时,第一次调用确实更新了start_id,因此第二次调用应该返回新的一批行,但它返回空,其余的后续调用也是如此。start_id的调试值在第一次调用更新后保持不变。当我用调试值替换查询中的?并在mysql控制台中运行查询时,它返回batch_size行数。我不明白这是怎么回事。

pollingHandler = id -> {
   LOGGER.debug("start_id: {}", start_id);
   LOGGER.debug("batch_size: {}", batch_size);

   mysqlClient
    .preparedQuery(FETCH_SAMPLE_DATA_QUERY)
    .execute(Tuple.of(start_id,batch_size))
    .onSuccess(rows -> {
      LOGGER.debug("Processing {} rows", rows.size());
      
      if (rows.size() > 0) {
        RowIterator<Row> rowIterator = rows.iterator();
        processRows(rowIterator); // this updates start_id so that the next query starts from somewhere else
      }
      vertx.setTimer(config.getLong("polling-interval"), pollingHandler);
    })
    .onFailure(err -> {
      LOGGER.error(err.getMessage(),err);
      vertx.setTimer(config.getLong("polling-interval"), pollingHandler);
    });
 };

 // Schedule the first execution
 vertx.setTimer(config.getInteger("polling-interval"), pollingHandler);
uurv41yg

uurv41yg1#

不管出于什么原因,上面的预处理语句查询在mariadb 10.5上运行得很好,但在MySQL 8.0.25上运行失败,即使max_prepared_stmt_count被设置为非零值。我将代码从使用preparedQueryconnectOptions.setCachePreparedStatements(true)改为简单地使用query和串联参数,它开始工作了。不知道是不是bug。

相关问题