我们正在将Sequelize与带有读写数据库的AWS Aurora Postgresql数据库一起使用。将Sequelize配置为使用读取副本和写入数据库。
我们有一个users
表和follows
表。 User
对象类型具有作为子查询的字段,例如,用户的字段afterCount:
...
followingCount: {
type: new GraphQLNonNull(GraphQLInt),
resolve(user) {
return db.Follower.count({
where: { followerId: user.id, status: "Approved" }
});
}
},
当我们向用户的follows
表中添加一条记录,然后返回该用户实例时,followingCount
不会更新。我有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();
用户实例(followingCount
)上的followingUser
字段不返回最新计数,即使它存在于主数据库/写入数据库中。
有哪些选项?有什么办法可以将我的突变包装在一个块中,以便其中执行的任何事情都可以使用Master / Write数据库吗?可以将其包装在交易帮助中,如果可以的话,如何将交易传递给我的
任何帮助表示赞赏
psql 9.6.8
sequelize 4.38.0
答案 0 :(得分:0)
在PostgreSQL中,复制可以通过多种方式进行:
如果您正在运行异步复制,则在主服务器(主服务器)上已提交事务后,数据可能会到达从服务器上。通常复制延迟很小。
您可以同步复制到任意数量的从站,以确保COMMIT仅在所需数量的PostgreSQL服务器确认后才有效。
所以我认为您正在使用异步复制,您需要转向同步复制。
为了设置同步复制,您需要在postgresql.conf文件中配置sync_standby_name和sync_commit参数。 sync_commit参数可以具有以下值:off,on,remote_write,remote_apply(Postgres 9.6功能)和本地。
答案 1 :(得分:0)
我可以通过在要返回的数据库对象上调用reload()
并将其传递给useMaster: true
followingUser.reload({ useMaster: true });
我创建了带有续集的票证,如果对任何人都有用,它将具有更多上下文:https://github.com/sequelize/sequelize/issues/9971