为了账号安全,请及时绑定邮箱和手机立即绑定

如何正确断开 MongoDB 客户端

如何正确断开 MongoDB 客户端

Go
长风秋雁 2022-07-11 16:26:58
据我了解,您必须在使用完 MongoDB 后断开与它的连接,但我不完全确定如何正确操作var collection *mongo.Collectionvar 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 已经断开连接。所以问题是——处理这个案子的正确方法是什么?
查看完整描述

2 回答

?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

您的应用程序需要在所有服务或存储库中连接 MongoDB 客户端,因此如果您在应用程序包中分离了 MongoDB 客户端连接和断开功能,则更容易。您不需要连接 MongoDB 客户端,如果您的服务器正在启动,如果您的服务或存储库需要 MongoDB 客户端连接,您可以先连接。


// db.go

package application


import (

    "context"

    "fmt"

    "go.mongodb.org/mongo-driver/mongo"

    "go.mongodb.org/mongo-driver/mongo/options"

    "log"

    "os"

)


var client *mongo.Client


func 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 interface

func (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

}


查看完整回答
反对 回复 2022-07-11
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

在 Python 中执行此操作的最佳方法是将数据库连接编写为单例,然后使用“atexit”模块来装饰断开连接的函数。这确保了连接只被实例化一次,因为我们不想打开多个连接,因为我们想要共享一个连接,并且在程序结束时连接断开。


import atexit

from pymongo import MongoClient


class MongoDB:

'''define class attributes'''

__instance = None


@staticmethod

def getInstance():

    """ Static access method. """

    # if the instance doesnt exist envoke the constructor

    if MongoDB.__instance == None:

        MongoDB()

    # return instance

    return MongoDB.__instance


def __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.register

def 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")

如果有人知道更好的设计模式,请随时发表评论,这只是我想出的似乎效果很好的东西。


查看完整回答
反对 回复 2022-07-11
  • 2 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信