对象化列表在一个实体中的一致性

Objectify list consistency in one entity

我尝试在 App Engine 上为我的 android 应用制作聊天解决方案。 A 决定不将发送到主题的所有消息保存在单独的实体(如 ChatMessage 或类似的实体)中,我可以将它们保存在主题实体内的字符串列表中,如下所示:

@Entity
public class Topic {
    @Id
    public String id;
    public List<Long> users = new ArrayList<Long>(2);
    public Long lastChangeTime;
    public LinkedList<String> messages = new LinkedList<String>();
}

我想到这个是因为通常存储每条消息的主题 ID 比消息字符串本身的数据更多。 :S 我不知道的是,这个列表可以强一致吗?
这就是我向主题添加新消息的方式:

    // 2. get topic if it exists or create a new if not
    Topic topic = ofy().load().key(Key.create(Topic.class, topicId)).now();
    if (topic == null) {
        topic = new Topic(senderId, recipientId);
    }

    // 3. add message
    // this method adds the new string into the topic and update the 
    // last change time
    topic.addMessage(senderId, recipientId, send.message);

    // 4. save topic & the new message
    ofy().save().entity(topic).now();

所以如果两个用户同时发送一条消息,会不会发生第一个用户加载主题,添加他的消息,但同时第二个用户已经加载了主题(没有第一个用户的消息) 并添加他自己的新消息。先存话题先。但是第二个可以覆盖第一个用户之前的保存吗?或者会发生什么?

如果它可能发生,我该如何避免这种情况,请记住它是一个高写入率实体,所以我需要超过 1/秒的写入速度!

谢谢,并致以最诚挚的问候。

What I don't know is, can this list strong consistent?

Consistency 由实体组和查询决定,而不是属性。

So if two users send a message at the same time, can it happens that the first user load the Topic, add his message, but in the same time the second user already loaded the topic (without the first user's message) and add his own new message. The first save the topic first. But can the second override the previous save of first user? Or what happens?

您需要在 transaction 中执行此操作。如果在事务中抛出 ConcurrentModificationException(您的示例场景),那么 Objectify 将为您重试。

但是,为了避免争用,您需要更改数据模型。你可以有一个 Message class 和一个 Topic,像这样:

@Entity
public class Topic {
    @Id
    String id;
    List<Long> users = new ArrayList<Long>(2);
    Long lastChangeTime;
}

以及引用一个或多个主题的消息(我在这里做出假设):

@Entity
public class Message {
    @Id
    Long id;
    Long lastChangeTime;
    @Index
    Ref<Topic> topic;
}

topic 上的 @Index 注释将允许您通过 topic 查询 Message。如果您的消息可以在多个主题中,您可以将 Ref<Topic> 更改为相同的 List