2016-07-06 40 views
1

我有一个使用rethinkdb的nodejs写入的添加。在启动时,应用程序会执行一堆数据库设置,包括创建必要的表(如果它们不存在)。代码(简体)看起来像这样:Rethinkdb竞争条件创建表

r.tableList().run(conn).then(existingTables => 
    requiredTables 
     .filter(t => existingTables.indexOf(t) === -1) 
     .map(name => r.tableCreate(name).run(conn))); 

这工作正常。问题是,该应用程序正在Docker容器内运行,例如,我需要能够使用docker-compose scale app=3进行扩展。部署作业运行时,会立即创建三个新容器,每个容器都会创建一组导致数据库问题的表,这些问题需要手动解决。我想我可以理解为什么发生这种情况,但我看不出如何解决它。我曾想过要将它全部写入一个查询中,但真正的用处比较复杂(即创建索引,运行迁移,填充示例数据),我不认为我可以做任何事情在单个查询中的很多。

回答

0

RethinkDB目前不保证管理操作是原子操作。要做的最好的事情可能是分离出管理操作(创建数据库,表和索引),并在仅在一个容器中运行的单独设置步骤中运行这些操作。

+0

是的,我想到了这一点,但我真的不想为此创建单独的服务。此外,自举会变得棘手,因为我需要等待数据库操作在启动主应用程序容器之前运行 - 据我所知,docker-compose不支持这种链接,所以我需要手动编写脚本。 – aquavitae

+0

你也许可以让应用程序容器等待数据库准备就绪,而不是等待启动它们直到它准备好。 (另外,如果您不想创建单独的服务,另一种选择是使您的应用服务足够智能以解决冲突的数据库/表名称,例如,在发生冲突时始终删除具有最高UUID的服务。你可以通过查看'rethinkdb'数据库中的相关系统表来实现。) – mlucy