gopkg.in/mgo.v2中的并发(Mongo,Go)

时间:2017-02-27 17:25:26

标签: mongodb go mgo

我希望在Go中编写的webapp中使用MongoDB。

我可以拥有一个mgo.Session并在网络应用中同时使用它。例如在http.Handler

或者我应该致电Session.CopySession.Close - >制作会议池。

在某些地方,我认为游泳池已在mgo.Session内实施,而且我可以同时使用会话,而我在其他地方读到我需要CopyClose

2 个答案:

答案 0 :(得分:6)

mgo.Session对于并发使用是安全的。引用其文档:

  

所有Session方法都是并发安全的,可以从多个goroutine中调用。

但这并不意味着您不应在拨打时获得的初始会话上通过拨打Session.Copy()Session.Clone()来并行创建和使用更多内容。

并发安全并从使用更多内容中受益不会相互排斥(它们不是互斥)。虽然您可以使用来自任意数量的goroutine的单个mgo.Session,但这不会很好地扩展,但不会扩展。会话自动管理连接池,甚至可以管理多个服务器节点,但如果您使用单个Session,则您不会利用它。通过在每个请求的开头创建一个新的Session(如果需要),并在最后正确关闭它(使用Session.Close();最好使用defer调用),您正在服用可能同时使用多个连接的优点,可能是多个服务器节点(如果可用),从而更好地利用服务器资源;并获得更快的响应时间(从数据库,最终到您的HTTP最终用户)。调用Session.Close()不会关闭与服务器的基础连接,它只会将连接放回池中,准备被另一个会话接收。

另请参阅有关Session的使用的相关问题:mgo - query performance seems consistently slow (500-650ms)

答案 1 :(得分:3)

调用DialDialWithTimeoutDialWithInfo将建立连接池。如果您需要多个会话,则需要调用session.Copy()或session.New(),session.Copy()是首选,因为它将保留auth。这是一个例子:

假设您有一个UserService结构来处理所有用户数据库需求。请注意,这是我的头脑,所以可能会有一些语法错误,但这个想法就在那里。

type Userservice struct {
    DB *mgo.Session
}

func (s *Userservice) Create(u *User) error {
    sessionCopy := s.DB.Copy()
    defer sessionCopy.Close()

    db := sessionCopy.DB("test_db")
    col := db.C("users")

    if err := col.Insert(u); err != nil {
        return err
    }
}