【问题标题】:mongodb: should i always use the 'safe' option on updatesmongodb:我应该总是在更新时使用“安全”选项吗
【发布时间】:2011-06-25 20:55:06
【问题描述】:

在处理 mongodb 时,我应该什么时候在查询中使用 {safe: true}?

现在我使用“安全”选项来检查我的查询是否已成功插入或更新。但是,我觉得这可能是过度杀戮。

我是否应该假设 99% 的时间,我的查询(假设它们被正确编写)将被插入/更新,而不必担心检查它们是否成功输入?

想法?

【问题讨论】:

    标签: mongodb database


    【解决方案1】:

    这是另一个适合选择不安全写入的用例:您正在以非常短的顺序进行大量写入。在这种情况下,您可能会执行多次写入,然后调用 get last error 来查看其中是否有任何失败。

    collection.setWriteConcern(WriteConcern.NORMAL)
    collection.getDB().resetError()
    List<
    for (Something data : importData) {
        collection.insert(makeDBObject(data))
    }
    collection.getDB().getLastError(WriteConcern.REPLICAS_SAFE).throwOnError()
    

    如果此块无异常成功,则所有数据均已成功插入。如果出现异常,则一个或多个写入操作失败,您将需要重试它们(或检查唯一索引违规等)。在现实生活中,您可能每 10 次左右的写入调用一次 getLastError,以避免重新提交大量请求。

    这种模式在执行大量数据的批量插入时性能非常好。

    【讨论】:

    • 由于错误必须异步返回,您怎么知道您已经等待足够长的时间等待任何错误到达?
    • Leopd:错误不会异步返回。 getLastError 调用会阻塞,直到收到答案。
    • 但是写入是异步提交的。因此,除非 getLastError 刷新写入缓冲区,否则它只会报告已经发生的错误,并且无法知道尚未完成的写入。
    • @Leopd:getLastError 等待所有写入完成,然后报告状态。
    • 太棒了。感谢您澄清这一点!
    【解决方案2】:

    假设当您说查询时,您实际上是指写入/插入(您问题的措辞让我想到了这一点),那么可以使用 Write Concern(安全、无、fsync 等)来获得更快的速度和更低的安全性是可以接受的,必要时可以降低速度并提高安全性。

    举个例子,一个假设的 Facebook 风格的应用程序可以对“喜欢”使用不安全的写入,而对密码更改使用非常安全的写入。这背后的逻辑是,一秒钟内会发生数千次“点赞”式更新,即使丢失也无所谓,而密码更新发生的频率较低,但成功至关重要。

    因此,请尝试根据您的速度和数据完整性要求,根据您正在执行的更新类型来调整您的 Write Concern 选择。

    【讨论】:

      【解决方案3】:

      仅在写入时需要安全,在读取时不需要。查询只是读取。

      【讨论】:

        猜你喜欢
        • 2012-01-10
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多