我们在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();
}
});
}
}
答案 0 :(得分:0)
我认为您不希望JDBCClient
成为static
。
我认为您正在重复使用该池。
通过docs,他们解释说:
在大多数情况下,您需要在不同的数据源之间共享数据源 客户端实例。
E.g。通过部署多个实例来扩展应用程序 您的Verticle并且您希望每个Verticle实例共享相同的内容 数据源,所以你最终不会有多个池
您可以按照以下方式执行此操作:
JDBCClient client = JDBCClient.createShared(vertx, config);
没有解释或将客户端设为静态的示例。
我认为您正在创建同一Verticle
的多个实例。如果你把它减少到1个实例(所以只有一个事件循环),我猜这个问题会消失吗?