猿问

如何正确断开 MongoDB 客户端

据我了解,您必须在使用完 MongoDB 后断开与它的连接,但我不完全确定如何正确操作


var collection *mongo.Collection

var ctx = context.TODO()


func init() {

    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017/")

    client, err := mongo.Connect(ctx, clientOptions)

    if err != nil {

        log.Fatal(err)

    }

    //defer client.Disconnect(ctx)


    err = client.Ping(ctx, nil)

    if err != nil {

        log.Fatal(err)

    }

    fmt.Println("Connected successfully")


    collection = client.Database("testDB").Collection("testCollection") //create DB

}

有注释掉的函数调用 defer client.Disconnect(ctx) ,如果所有代码都发生在 main() 函数中,这将正常工作,但由于在 init() 执行后立即调用 defer,因此 main() 函数中的 DB 已经断开连接。


所以问题是——处理这个案子的正确方法是什么?


长风秋雁
浏览 161回答 2
2回答

拉莫斯之舞

您的应用程序需要在所有服务或存储库中连接 MongoDB 客户端,因此如果您在应用程序包中分离了 MongoDB 客户端连接和断开功能,则更容易。您不需要连接 MongoDB 客户端,如果您的服务器正在启动,如果您的服务或存储库需要 MongoDB 客户端连接,您可以先连接。// db.gopackage applicationimport (    "context"    "fmt"    "go.mongodb.org/mongo-driver/mongo"    "go.mongodb.org/mongo-driver/mongo/options"    "log"    "os")var client *mongo.Clientfunc ResolveClientDB() *mongo.Client {    if client != nil {        return client    }    var err error    // TODO add to your .env.yml or .config.yml MONGODB_URI: mongodb://localhost:27017    clientOptions := options.Client().ApplyURI(os.Getenv("MONGODB_URI"))    client, err = mongo.Connect(context.Background(), clientOptions)    if err != nil {        log.Fatal(err)    }    // check the connection    err = client.Ping(context.Background(), nil)    if err != nil {        log.Fatal(err)    }    // TODO optional you can log your connected MongoDB client    return client}func CloseClientDB() {    if client == nil {        return    }    err := client.Disconnect(context.TODO())    if err != nil {        log.Fatal(err)    }    // TODO optional you can log your closed MongoDB client    fmt.Println("Connection to MongoDB closed.")}主要:func main() {    // TODO add your main code here    defer application.CloseClientDB()}在您的存储库或服务中,您现在可以轻松获得 MongoDB 客户端:// account_repository.go// TODO add here your account repository interfacefunc (repository *accountRepository) getClient() *mongo.Client {    if repository.client != nil {        return repository.client    }    repository.client = application.ResolveClientDB()    return repository.client}func (repository *accountRepository) FindOneByFilter(filter bson.D) (*model.Account, error) {    var account *model.Account    collection := repository.getClient().Database("yourDB").Collection("account")    err := collection.FindOne(context.Background(), filter).Decode(&account)    return account, err}

开心每一天1111

在 Python 中执行此操作的最佳方法是将数据库连接编写为单例,然后使用“atexit”模块来装饰断开连接的函数。这确保了连接只被实例化一次,因为我们不想打开多个连接,因为我们想要共享一个连接,并且在程序结束时连接断开。import atexitfrom pymongo import MongoClientclass MongoDB:'''define class attributes'''__instance = None@staticmethoddef getInstance():    """ Static access method. """    # if the instance doesnt exist envoke the constructor    if MongoDB.__instance == None:        MongoDB()    # return instance    return MongoDB.__instancedef __init__(self) -> None:    """ Virtually private constructor. """    if MongoDB.__instance != None:        raise Exception("Singleton cannot be instantiated more than once")    else:        print("Creating MongoDB connection")        # set instance and instance attributes        self.client = MongoClient(config.CONNECTION_STRING)        MongoDB.__instance = self@staticmethod@atexit.registerdef closeConnection():    '''     Python '__del__' aka destructor dunder doesnt always get called    mainly when program is terminated by ctrl-c so this method is decorated    by 'atexit' which ensures this method is called upon program termination    '''    if MongoDB.__instance != None:        MongoDB.__instance.client.close()        print("Closing Connections")如果有人知道更好的设计模式,请随时发表评论,这只是我想出的似乎效果很好的东西。
随时随地看视频慕课网APP

相关分类

Go
我要回答