cursor.noCursorTimeout()

Definition

noCursorTimeout()方法具有以下原型形式:

db.collection.find(<query>).noCursorTimeout()

Behavior

会话空闲超时将覆盖 noCursorTimeout

从 MongoDB 3.6 开始,MongoDB 驱动程序和mongo shell 将所有操作与server session关联,但未确认的写操作除外。对于未与会话明确关联的操作(即使用Mongo.startSession()),MongoDB 驱动程序和mongo Shell 创建隐式会话并将其与该操作相关联。

如果会话空闲时间超过 30 分钟,则 MongoDB 服务器会将会话标记为已过期,并可以随时关闭它。当 MongoDB 服务器关闭会话时,它还会终止所有正在进行的操作并打开与该会话关联的游标。这包括配置为noCursorTimeoutmaxTimeMS大于 30 分钟的光标。

考虑一个使用cursor.noCursorTimeout发出db.collection.find()的应用程序。服务器返回游标以及由find()cursor.batchSize()定义的一批文档。每当应用程序从服务器请求新一批文档时,会话都会刷新。但是,如果应用程序花费超过 30 分钟的时间来处理当前一批文档,则该会话将被标记为已过期并关闭。当服务器关闭会话时,它也会杀死游标尽管noCursorTimeout配置的游标。当应用程序请求下一批文档时,服务器将返回错误。

对于返回游标的操作,如果游标可能闲置了 30 分钟以上,请使用Session.startSession()在显式会话中发出操作,并使用refreshSessions命令定期刷新该会话。例如:

var session = db.getMongo().startSession()
var sessionId = session.getSessionId().id

var cursor = session.getDatabase("examples").getCollection("data").find().noCursorTimeout()
var refreshTimestamp = new Date() // take note of time at operation start

while (cursor.hasNext()) {

  // Check if more than 5 minutes have passed since the last refresh
  if ( (new Date()-refreshTimestamp)/1000 > 300 ) {
    print("refreshing session")
    db.adminCommand({"refreshSessions" : [sessionId]})
    refreshTimestamp = new Date()
  }

  // process cursor normally

}

在示例操作中,db.collection.find()方法与显式会话关联。游标使用cursor.noCursorTimeout()配置,以防止服务器在空闲时关闭游标。 while循环包括一个块,该块使用refreshSessions每 5 分钟刷新一次会话。由于会话将永远不会超过 30 分钟的空闲超时,因此游标可以无限期保持打开状态。

对于 MongoDB 驱动程序,请参考driver documentation以获取有关创建会话的说明和语法。

首页