可以并发地向共享数据库写入数据吗?

6

我正在使用Python的multiprocessing库来生成多个进程,每个进程都会写入一个共享的(MongoDB)数据库。这样做是否安全?还是说这些写操作会相互覆盖?

2个回答

4
只要确保为每个工作进程创建单独的数据库连接,同时访问数据库是完全安全的。它们发出的任何更改数据库的查询将被单独应用,通常按照数据库接收到的顺序。在大多数情况下,这是安全的,但是:
  • 如果您的进程只是将文档插入数据库,每个插入通常会创建一个单独的对象。

    例外情况是,如果您明确为文档指定了_id,并且该标识符已在集合中使用过,则插入将失败。(因此不要这样做:省略_id,MongoDB将始终为您生成唯一值。)

  • 如果您的进程正在从数据库中删除文档,则如果另一个进程已经删除了相同的对象,则操作将失败。(尽管如此,这并不严格意义上的失败;这只是意味着有人比你先到了那里。)

  • 如果您的进程正在更新数据库中的文档,则情况变得更加复杂。

    只要每个进程都在更新不同的文档,那么就没问题。

    如果多个进程同时尝试更新同一文档,则需要小心处理。替换对象上的值的更新将按顺序应用,这可能会导致一个进程所做的更改被另一个进程意外地覆盖。您应该小心避免指定您不打算更改的字段。使用MongoDB的update operators可以有助于以原子方式执行复杂操作,例如更改字段的数字值。

请注意,“同时”并不一定意味着操作在完全相同的时间进行。它更普遍地意味着两个进程在使用同一文档的时间上存在“重叠”,例如。
Process A                    Process B
---------                    ---------
Reads object from DB         ...
working...                   Reads object from DB
working...                   working...
updates object with changes  working...
                             updates object with changes

在上述情况下,进程A进行的一些更改可能会无意中被进程B覆盖。

如果您将相同的连接用于所有工作进程,会发生什么? - Jessica
@Jessica 不好的事情。(可能有多个进程同时尝试向连接写入内容,MongoDB 会收到混乱的信息并且可能会断开连接。)所以不要这样做。 :) - user149341

2
简而言之,让你的数据库处理数据库操作的并发是完全合理的(实际上也是首选)。任何相关的数据库驱动程序(包括MongoDB)都会自动处理并发操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接