Sequelize.js 具有Sequelize的副本读取数据库的竞争条件

Sequelize.js 具有Sequelize的副本读取数据库的竞争条件,sequelize.js,psql,database-replication,Sequelize.js,Psql,Database Replication,我们将Sequelize与AWS Aurora Postgresql数据库以及读写数据库一起使用。Sequelize配置为使用读副本和写数据库 我们有一个users表,下面是表。用户对象类型具有作为子查询的字段,例如,以下字段取决于用户: ... followingCount: { type: new GraphQLNonNull(GraphQLInt), resolve(user) { return db.Follower.count({ where: { foll

我们将Sequelize与AWS Aurora Postgresql数据库以及读写数据库一起使用。Sequelize配置为使用读副本和写数据库

我们有一个
users
表,下面是
表。
用户
对象类型具有作为子查询的字段,例如,以下字段取决于用户:

...
followingCount: {
  type: new GraphQLNonNull(GraphQLInt),
  resolve(user) {
    return db.Follower.count({
      where: { followerId: user.id, status: "Approved" }
    });
  }
},
当我们为用户向
follows
表中添加记录,然后返回该用户实例时,
followCount
不会更新。我有99%的信心,这是因为它正在从没有数据的副本/读取数据库中读取数据。我通过禁用复制副本并看到问题消失来验证这一点

我不太愿意将
useMaster
选项添加到这些字段中,因为它否定了我们的并发策略

下面是我正在调用的确切代码:

const followingUser = await db.User.findOne({
  where: {
    id
  }
});

await db.Follower.create({
  followerId: getCurrentUserId(context),
  followingId: id,
  status: followingUser.privateProfile ? "Pending" : "Approved"
});

return followingUser.reload();
用户实例(
followuser
)上的
followCount
字段没有返回最新计数,即使它存在于主/写数据库中

有什么选择?是否有某种方法可以将我的突变封装在一个块中,以便在其中执行的任何操作都使用Master/Write数据库?将其包装在事务中是否有帮助?如果有,如何将事务传递给我的客户

谢谢你的帮助

psql 9.6.8


PostgreSQL中的sequelize 4.38.0

可以通过多种方式进行复制:

  • 同步的
  • 异步的
如果正在运行异步复制,则在主服务器(主服务器)上提交事务后,数据可能会命中从属服务器。通常会有很小的复制延迟

您可以同步地将复制到所需数量的从属服务器,以确保提交仅在所需数量的PostgreSQL服务器确认后才有效

同步事务只能在足够数量的从属服务器确认写入时返回。 因此,我认为您正在使用异步复制,您需要转向同步复制

为了设置同步复制,您需要在postgresql.conf文件中配置synchronous_standby_name和synchronous_commit参数。synchronous_commit参数可以有以下值:off、on、remote_write、remote_apply(Postgres 9.6功能)和local


在PostgreSQL中,可以通过多种方式进行复制:

  • 同步的
  • 异步的
如果正在运行异步复制,则在主服务器(主服务器)上提交事务后,数据可能会命中从属服务器。通常会有很小的复制延迟

您可以同步地将复制到所需数量的从属服务器,以确保提交仅在所需数量的PostgreSQL服务器确认后才有效

同步事务只能在足够数量的从属服务器确认写入时返回。 因此,我认为您正在使用异步复制,您需要转向同步复制

为了设置同步复制,您需要在postgresql.conf文件中配置synchronous_standby_name和synchronous_commit参数。synchronous_commit参数可以有以下值:off、on、remote_write、remote_apply(Postgres 9.6功能)和local


我能够解决这个问题,方法是对我返回的DB对象调用
reload()
,并传递它
useMaster:true

followuser.reload({useMaster:true})


我用sequelize创建了一个票证,如果它对任何人都有帮助的话,它会有更多的上下文:

我可以通过调用我返回的DB对象上的
reload()
来解决这个问题,并传递它
useMaster:true

followuser.reload({useMaster:true})


我用sequelize创建了一张票证,如果它对任何人都有帮助,它会有更多的上下文:

亲爱的,我能听听你对z答案的意见吗?亲爱的,我能听听你对z答案的意见吗?谢谢你花时间回复。它不像AWS Aurora那样提供同步复制,不过感谢您花时间回复。但它不像AWS Aurora那样提供同步复制