在Vertx中异步运行多个Sql查询(Vert.x 3)

时间:2016-07-10 19:30:10

标签: java mysql database-connection vert.x

我使用的是vertx-mysql-postgresql-client-3.3.0和vertx-sql-common-3.3.0 我最初想过使用Batch操作来插入多个语句但看起来像这样(http://vertx.io/docs/vertx-sql-common/java/#_batch_operations)并没有在vertx-mysql-postgres-client中实现。

处理db数据的代码是:

SQLConnection sqlConnection;
 List <JsonArray> targetParams = new ArrayList();
 for (String key : targetObject.getTargets().keySet()) {
    targetParams.add(new JsonArray().add(key).add(targetObject.getTargets().get(key)).add(targetObject.getId()));
 }
 int[] i = {targetObject.getTargets().size()};
 while(i[0]>=0) {
   sqlConnection.updateWithParams("INSERT INTO Targets (name,  id,language) VALUES (?,?,?)", taglineParams.get(i[0] - 1), result ->
{           
  if (result.succeeded()) {
      i[0]--;
 }

else { badRequest(context, "Error inserting error code: " +   result.cause().toString());
   }
 }); 
}

AsyncResult处理程序代码:

Handler<AsyncResult<SQLConnection>> sqlConnectionHandler = new Handler<AsyncResult<SQLConnection>>() {
    @Override
    public void handle(AsyncResult<SQLConnection> res) {
        if (res.succeeded()) {
            sqlConnection = res.result();
        } else {
            logger.error("Unable to create SQL connection: " + res.cause().toString());
        }
    }
};

这个不起作用,并在首先插入后给出了Thread Blocked错误。

知道如何让多个插件工作吗?

3 个答案:

答案 0 :(得分:1)

Vert.x是一个异步框架,但代码使用的是不起作用的同步构造。有一个while循环,直到变量大于0.但控制变量的更新在异步处理程序上更新,这意味着它不会在循环内被调用。

知道这个循环将会永远运行&#34;直到JVM线程调度程序将停止它运行其他线程(最终将更新控件var)。既然调度程序已经停止了线程,Vert.x也会通知您阻止了事件循环,这意味着您应该修改代码。

我建议在大sql语句中连接SQL语句并立即执行,或者使用for循环。请注意,for循环也不是100%安全。假设您正在插入1M行,您还可以轻松使用超过2秒的CPU时间,并且您将再次收到警告。

好的解决方案是异步循环,或者以RX为例。

答案 1 :(得分:0)

我强烈建议在这些情况下使用CountDownLatch:

CountDownLatch latch = new CountDownLatch(targetObject.getTargets().size());
for (JsonArray params : targetParams) {
    sqlConnection.updateWithParams("INSERT INTO Targets (name,  id,language) VALUES (?,?,?)", params, result ->
    {
        if (!result.succeeded()) {
            badRequest(context, "Error inserting error code: " +   result.cause().toString());
        }
        latch.countDown();
    });
}

latch.await(3, TimeUnit.SECONDS);

这对Vert.x来说仍然不好,因为它会阻塞线程,所以你也应该考虑更改逻辑,而不是等待进程完成。

答案 2 :(得分:0)

我看到办公室API,batch operation,也许你可以使用它。

List<JsonArray> batch = new ArrayList<>();
batch.add(new JsonArray().add("joe"));
batch.add(new JsonArray().add("jane"));

connection.batchWithParams("INSERT INTO emp (name) VALUES (?)", batch, res -> {
  if (res.succeeded()) {
    List<Integer> result = res.result();
  } else {
    // Failed!
  }
});