Vertx应用中简单数据库更新操作耗时3分钟的排查求助
Vertx 中简单数据库更新操作耗时3分钟的排查分析
我在Java Vertx应用里执行一个非常简单的数据库更新操作,但耗时居然长达3分钟。下面是控制台输出和相关代码,求帮忙排查原因。
控制台输出
2022-07-19 11:54:32.039+0430 [vert.x-eventloop-thread-1] DEBUG com.job.PrintJobHandler - onSuccess for startPrintJob() Job Completed Successfully!!!! 2022-07-19 11:54:32.039+0430 [vert.x-eventloop-thread-1] DEBUG com.dao.JobDao - Inside setJobFinishedDate() 14 2022-07-19 11:54:32.039+0430 [vert.x-eventloop-thread-1] DEBUG com.dao.JobDao - Tuple for Parent UID values: [2022-07-19 11:54:32,14] 2022-07-19 11:57:45.733+0430 [vert.x-eventloop-thread-1] DEBUG com.dao.JobDao - Updated job table's finished_on column!!!!!!!!!!!!!!!!!!!!!!!!! 2022-07-19 11:57:45.733+0430 [vert.x-eventloop-thread-1] DEBUG com.job.PrintJobHandler - Job Completed Successfully!!!! 2022-07-19 11:57:45.734+0430 [vert.x-eventloop-thread-1] DEBUG com.job.PrintJobHandler - onSuccess for startPrintJob() Server sent msg --- Finished printing Job ID::::: 14
相关代码
调用更新方法的代码
startPrintJob(jobID, context) .onFailure(error -> { LOG.debug("startTest() Failed: ", error); }) .onSuccess(res -> { LOG.debug(" onSuccess for startPrintJob() " + res); jobDao.setJobFinishedDate(jobID) .onSuccess(result -> { LOG.debug(res); String updatedStatus = "Server sent msg --- Finished printing Job ID::::: "+jobID; context.response() .setStatusCode(200) .putHeader("content-type", "application/json; charset=utf-8") .end(Json.encodePrettily(updatedStatus)); LOG.debug(" onSuccess for startPrintJob() " + updatedStatus); }); });
更新方法实现
public Future<String> setJobFinishedDate(int jobID) { Promise<String> promise = Promise.promise(); LOG.debug("Inside setJobFinishedDate() "+jobID); LocalDateTime issuedAt = LocalDateTime.now(); DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); Tuple batch = Tuple.of(issuedAt.format(format), jobID); LOG.debug("Tuple for Parent UID values: " + batch.deepToString()); // Execute the query db.preparedQuery("UPDATE job SET finished_on=? WHERE id=?;").execute(batch, res -> { if (res.succeeded()) { LOG.debug("Updated job table's finished_on column!!!!!!!!!!!!!!!!!!!!!!!!! "); promise.complete("Updated job table's finished_on column!!"); } else { System.out.println("Batch failed for UPDATE job table's finished_on column!!" + res.cause()); } }); return promise.future(); }
可能的排查方向
- 数据库锁等待:目标行(id=14的job记录)可能被其他事务持有锁未释放,导致UPDATE语句等待。可以通过数据库工具查看锁状态(比如MySQL用
SHOW ENGINE INNODB STATUS,PostgreSQL用SELECT * FROM pg_locks)。 - 连接池资源耗尽:检查Vertx数据库连接池的配置(最大连接数、等待超时等),确认是否有请求在等待空闲连接。
- 索引缺失:确认
job表的id字段是否为主键或有索引,无索引会导致全表扫描,拖慢更新速度。 - 时间类型不匹配:代码中将LocalDateTime转为字符串传入,若
finished_on是数据库的datetime/timestamp类型,直接传入LocalDateTime对象可避免类型转换的隐性问题。 - 数据库性能瓶颈:查看数据库的CPU、磁盘IO负载,开启慢查询日志,确认这条UPDATE是否被标记为慢查询。
- 事件线程阻塞:虽然日志显示操作在eventloop线程,但需确认数据库驱动是否真的异步执行,避免其他阻塞操作占用事件线程。
内容的提问来源于stack exchange,提问作者ZAJ
相关产品推荐
相关产品推荐

