对象化 - 在短时间内多次写入同一实体,有或没有事务

Objectify - many writes to same entity in short period of time with and without transaction

我正在做的是创建一个交易

1) 实体 A 的计数器更新为 +1
2) 一个新的实体 B 被写入数据存储。

看起来像这样:

WrappedBoolean result = ofy().transact(new Work<WrappedBoolean>() {
    @Override
    public WrappedBoolean run() {

        // Increment count of EntityA.numEntityBs by 1 and save it
        entityA.numEntityBs = entityA.numEntityBs +1;
        ofy().save().entity(entityA).now();

        // Create a new EntityB and save it
        EntityB entityB = new EntityB();
        ofy().save().entity(entityB).now();

        // Return that everything is ok
        return new WrappedBoolean("True");

    }
});

我正在做的是统计 EntityB 的 entityA 有多少个。这两个操作需要在一个事务中进行,因此要么都发生保存,要么都不发生。

但是,许多用户可能会执行包含上述事务的 api 方法。我担心我可能 运行 遇到太多人试图更新 entityA 的问题。这是因为如果多个事务尝试更新同一个实体,则第一个提交的事务会获胜,但其他所有事务都会失败。

这引出了两个问题:

1) 我写的事务是不是一个坏主意,如果对 API 方法进行大量调用,注定会导致无法写入?有没有更好的方法来实现我想要做的事情?

2) 如果对不在事务中的实体进行大量更新(例如更新实体具有的计数器)怎么办 - 如果很多,您最终 运行 会遇到缩放问题吗更新是在短时间内进行的?数据存储如何处理这个问题?

对于这个冗长的问题,我们深表歉意,但我希望有人可以通过上述问题阐明该系统如何为我工作。谢谢

编辑:当我的意思是在短时间内对一个实体进行大量更新时,请考虑像 Instagram 这样的东西,你想在其中跟踪有多少 "likes" 一张照片。一些用户拥有数百万粉丝,当他们 post 一张新照片时,他们每秒可以获得 10-50 个赞。

数据存储允许每个实体组大约 1 write/second。可能看起来并不明显的是,独立实体(即没有父实体和子实体)仍然属于一个实体组 - 它们自己的实体组。因此,对同一独立实体的重复写入受到相同的速率限制。

超过写限制最终会导致写操作失败,类似TransactionFailedError(Concurrency exception.)

在事务外重复写入同一实体可能会相互覆盖。事务可以帮助解决这个问题——冲突的写入会自动重试几次。从这个角度来看,您的方法看起来不错。但它只有在平均写入速率保持在限制以下时才有效。

您可能想要阅读 Avoiding datastore contention. You need to shard your counter 以便能够以每秒 1 次以上的速率对事件进行计数。