我正在开发一个使用 java 和 mongoDB 作为后端数据库的 Web 项目。要打开一次连接并为项目中包含的每个服务重复使用相同的连接,我遵循以下 URL
mongodb open connection issue 。为了关闭打开的连接,我在网站 session 的用户注销期间使用函数 MongoDBClass.INSTANCE.close();
。但问题是,一旦用户登录 session 再次产生以下错误java.lang.IllegalStateException:状态应该是:打开
。这意味着连接未打开,MongoDBClass INSTANCE
未重新初始化,因此MongoClient
没有重新打开连接。但是在服务器重新启动后,第一次登录可以正常工作。当我在注销用户 session 期间调用 close 方法后,如何在不重新启动服务器的情况下再次建立新连接。我正在使用以下代码
public enum MongoDBClass {
INSTANCE;
private static final String MONGO_DB_HOST = "hostURL";
private Mongo mongoObject;
private DB someDB;
String DB_NAME = null;
MongoClientOptions options = null;
MongoDBClass() {
options = MongoClientOptions.builder().connectionsPerHost(100)
.readPreference(ReadPreference.secondaryPreferred()).build();
mongoObject = new MongoClient(new ServerAddress(MONGO_DB_HOST, 27001),
options);
someDB = mongoObject.getDB(Nutans_Mongo.getNameOFDB());}}
public DB getSomeDB() {
return someDB;
}
public void setSomeDB(String dbName) {
someDB = mongoObject.getDB(dbName);
DB_NAME = dbName;
}
public String close() {
mongoObject.close();
return "true";
}
}
最佳答案
MongoClient
在内部维护一个连接池,因此无需为每个请求打开/关闭客户端。另外,Java 枚举不应该以这种方式使用。枚举具有的任何状态都应该是全局可用的,因为每个类加载器/VM 中只有一个枚举值实例。当您调用 close()
时,您将全局关闭该枚举的 MongoClient
。由于您在构造函数中打开连接,因此它永远不会重新打开,因为永远不会创建另一个INSTANCE
。
有多种方法可以确保 servlet 上下文中对象的类似单例的生命周期。一种方法是使用 CDI 创建 MongoClient
并将其注入(inject)到您的 servlet 中。使用 ServletContextListener 和静态字段是另一种方法,虽然稍微不那么美味。
关于java - 调用 close 方法后打开 MongoDB 连接的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30045127/