db操作(Sql Common和JDBC客户端)在不同的事件循环中执行

时间:2016-06-07 08:02:43

标签: vert.x

我们在Verticle中使用rabbitmq来接收消息。我们将Vert.x Common SQL接口作为单独的jar文件包装为DBHelper

DBHelper在rabbitmq verticle start()中初始化。

每次收到消息时,都会调用DBHelper来更新数据库中的列。但是当两个消息处于非常封闭的点时,我们观察到的是在不同的事件循环中执行了两个db操作,这导致db中的列没有最新的值。例如,两条消息(一条带有值,一条带有b值)来自rabbitmq(b值消息来自值消息)。 DB中列的值是a而不是b。

一些代码段:

rabbitmq verticle:

public final class MqVerticle extends AbstractVerticle {
    void start() {
        dbHelper = new DBHelper(vertx, db, username, password, 30);
    }

    //when message comes

    dbHelper.update(value);
}

DBHelper vertx:

public class DBHelper {

    private static JDBCClient jdbcClient;

    public static void init(Vertx vertx, String url, String user, String driver_class, String password, int max_pool_size) throws IOException {
        jdbcClient = JDBCClient.createShared(vertx, new JsonObject()
                .put("url", url)
                .put("driver_class", driver_class)
                .put("user", user)
                .put("password", password)
                .put("max_pool_size", max_pool_size));
    }

        public static void updateOne(String sql, JsonArray params, Consumer<Long> consumer) {
        jdbcClient.getConnection(ar -> {
            if(ar.failed()){
                throw new RuntimeException("connection failed:" + ar.cause().getLocalizedMessage());
            }else {
                SQLConnection connection = ar.result();
                connection.updateWithParams(sql, params, res -> {
                    if (res.failed()) {
                        throw new RuntimeException("sql failed:" + res.cause().getLocalizedMessage());
                    } else {
                        consumer.accept(res.result().getKeys().getLong(0));
                    }
                });
                connection.close();

            }
        });
    }

}

1 个答案:

答案 0 :(得分:0)

我认为您不希望JDBCClient成为static

我认为您正在重复使用该池。

通过docs,他们解释说:

  

在大多数情况下,您需要在不同的数据源之间共享数据源   客户端实例。

     

E.g。通过部署多个实例来扩展应用程序   您的Verticle并且您希望每个Verticle实例共享相同的内容   数据源,所以你最终不会有多个池

     

您可以按照以下方式执行此操作:

JDBCClient client = JDBCClient.createShared(vertx, config);

没有解释或将客户端设为静态的示例。

我认为您正在创建同一Verticle的多个实例。如果你把它减少到1个实例(所以只有一个事件循环),我猜这个问题会消失吗?