当前位置: 首页 > 知识库问答 >
问题:

我应该为mgo中的每个操作复制会话吗?

斜博超
2023-03-14

我想更新一个记录列表,所以我有两个选择,一个只使用一个会话,另一个为每个记录复制一个会话。所以,在我看来,第一种方法可能比第二种方法慢,但是第一种方法会导致创建太多会话吗?

1.use一个疗程

func (this *CvStoreServiceImpl) SetCvJobItemMeasureList(accessToken *base_datatype.ServiceAccessToken, versionPolicy string, jobItemList []*cv_common_type.CvJobItemMeasure) (err error) {
    session := this.session.Clone()
    defer session.Close()

    for _, jobItem := range jobItemList {
        objKey := &orm.ItemIdKey{
            VersionName: versionPolicy, //XXX
            ItemId:      jobItem.ItemId,
        }
        obj := orm.ConvertToCvJobItemMeasureObj(versionPolicy, jobItem)
        _, err2 := this.jobMeasureCollection.With(session).Upsert(objKey, obj)
        if nil != err2 {
            err = &common_error.NamedError{err2.Error()}
            this.logger.Println(err2.Error())
        }
    }
    return
}

2.为每条记录复制会话

func (this *CvStoreServiceImpl) SetCvJobItemMeasure(accessToken *base_datatype.ServiceAccessToken, versionPolicy string, jobItem *cv_common_type.CvJobItemMeasure) (err error) {
    session := this.session.Clone()
    defer session.Close()

    objKey := &orm.ItemIdKey{
        VersionName: versionPolicy, //XXX
        ItemId:      jobItem.ItemId,
    }
    obj := orm.ConvertToCvJobItemMeasureObj(versionPolicy, jobItem)
    _, err2 := this.jobMeasureCollection.With(session).Upsert(objKey, obj)
    if nil != err2 {
        err = &common_error.NamedError{err2.Error()}
        return
    }
    return
}

然后在forloop中调用此方法:

for _, item := range cvMeasure.GetJobList() {
    err = this.SetCvJobItemMeasure(accessToken, versionPolicy, item)
    if nil != err {
        return
    }
}

共有2个答案

徐秋月
2023-03-14

是的,复制一个会话以执行一个或多个操作是很好的,这样可以让mgo中的连接池提高性能。一台mongo服务器的默认限制为4096,以防止连接过多。

func newSession(consistency Mode, cluster *mongoCluster, timeout time.Duration) (session *Session) {
    cluster.Acquire()
    session = &Session{
        cluster_:    cluster,
        syncTimeout: timeout,
        sockTimeout: timeout,
        poolLimit:   4096,
    }
    debugf("New session %p on cluster %p", session, cluster)
    session.SetMode(consistency, true)
    session.SetSafe(&Safe{})
    session.queryConfig.prefetch = defaultPrefetch
    return session
}
姬魁
2023-03-14

首先,我们需要看到mgo和mgo之间的区别。一场复制()和mgo。一场克隆()。而go。一场Clone()返回一个新会话,该会话使用相同的套接字连接。这不一定是坏事,但请记住,在服务器端,每个连接都会分配一个堆栈。因此,会话将共享同一堆栈。根据您的用例,这可能会产生很大的不同。

问题就在这里——如果你为每条记录打开一个新的套接字连接,这会导致三次握手,这就是慢动作。重复使用同一个套接字可以减少这种开销,但仍有一些开销,并且具有上述缺点。

我倾向于做的是在每个长(er)运行的工作单元中建立一个新的连接。一个简单的例子说明了这一点:

package main

import (
    "fmt"
    mgo "gopkg.in/mgo.v2"
    bson "gopkg.in/mgo.v2/bson"
    "net/http"
)

var (
    Database *mgo.Database
)


// The listEntries lists all posts
func listPosts(w http.ResponseWriter, r *http.Request) {

    // We have a rather long running unit of work
    // (reading and listing all posts)
    // So it is worth copying the session   
    collection := Database.C("posts").With( Database.Session.Copy() )

    post  := bson.D{}
    posts := collection.Find(bson.M{}).Iter()

    for posts.Next(&post) {
        // Process posts and send it to w
    }

}

func main() {

    session, _ := mgo.Dial("mongodb://localhost:27017")

    Database := session.DB("myDb")

    // Count is a rather fast operation
    // No need to copy the session here
    count, _ := Database.C( "posts" ).Count()

    fmt.Printf("Currently %d posts in the database", count )

    http.HandleFunc("/posts", listPosts)
    http.ListenAndServe(":8080", nil)
}
 类似资料:
  • 一旦我们开始使用这个,Vaadin就会崩溃并停止工作。当为了调试而用内存中的映射替换外部缓存时,它会再次工作。 这似乎是由引起的,因为它将存储为会话属性。是,Javadoc显示: VaadinSession中的所有内容都应该是可序列化的,以确保与使用序列化持久化会话数据的方案兼容。 注意:我们也有一个使用Vaadin8的应用程序版本,这里也发生了同样的事情。这个问题似乎是由Vaadin Sprin

  • 根据SP启动的SSO流,用户尝试访问SP。由于用户未经身份验证,他被重定向到IDP,在那里输入他的凭据,成功登录后,IDP在用户的浏览器中设置cookie(在IDP的域下),并使用SAML响应将用户重定向回SP。一旦SP验证SAML响应,它就会创建自己的cookie/令牌,并在sp域下的用户浏览器中设置。 在后续请求中理想情况下应该发生什么: SP是否应该只依靠自己的cookie来获取用户信息 S

  • 应用申请和应用查看面板 我的应用 开发者可在该面板查看目前已在知晓云绑定的小程序 申请应用 填写要绑定在知晓云后台的小程序信息, 包括 AppName、AppID 以及 AppSecret 在小程序管理后台配置信任域名 | 配置项 | 域名 | | —————— | ———————————- | | request 合法域名 | https://sso.ifanr.com | | socket 合

  • 我目前正在学习Python从课程Python代码与Mosh.在他的课程中,他解释了使用Django构建一个网络应用程序。当我在网络服务器上运行我的应用程序时,我得到了一个错误“OPERATIONALERROR”,现在我被困在里面了。 我收到的错误图片:

  • 问题内容: 我目前正在将带有mgo lib的mongodb用于Web应用程序,但是我不确定我使用它的方式是否很好。 我初始化db会话并创建获取集合和文档值的变量,因此当我需要查询集合时,我使用变量来实现它。 像那样 : 那么,有没有最佳实践呢?谢谢 问题答案: 我建议不要使用这样的全局会话。相反,您可以创建负责所有数据库交互的类型。例如: 该设计有很多好处。一个重要的方面是,它允许您同时运行多个会