Google App Engine数据存储区中的多线程

高拉夫·萨赫德娃(Gaurav Sachdeva)

如何使从数据存储区获取和设置属性的操作安全,线程安全?

当前,我有将任务放入队列中的代码,每个任务执行一个任务,然后更新一个名为numberOfTasks的属性,该属性的类型为int。它基本上会获取此属性的当前值并对其进行递增。

但是,随着任务在队列中执行,由于线程问题,最终值将变得不正确。有时,两个任务试图同时更新属性,因此有时增量未完成。

任何人都可以帮助正确完成此工作吗?

数据存储区属性获取器方法:

private String doGet(String rowId) throws EntityNotFoundException {
    Key egsKey = KeyFactory.createKey(DATASTORE_KIND, rowId);

    Entity egsEntity = datastore.get(egsKey);

    // schema changed from String to Text type. Transparently handle that here.
    Object propertyValue = egsEntity.getProperty(PROPERTY_KEY);

    if (propertyValue instanceof String) {
        return (String) propertyValue;
    }

    Text text = (Text) propertyValue;

    return text.getValue();
}

数据存储区属性的设置方法:

private void doPut(String rowId, List<String> list) {
    Entity entity = new Entity(DATASTORE_KIND, rowId);
    entity.setProperty(PROPERTY_KEY, list);

    datastore.put(entity);
}

设置方法和获取方法:

public synchronized int getPendingUsersForProcessing() {
    String pendingUsersForProcessingAsString = null;
    try {
        pendingUsersForProcessingAsString = doGet(PENDING_USERS_FOR_PROCESSING);
        return Integer.valueOf(pendingUsersForProcessingAsString);
    } catch (NumberFormatException e) {
        throw new IllegalStateException("The num of last batches processed in Datastore is not a number: "
                + pendingUsersForProcessingAsString);
    } catch (EntityNotFoundException e) {
        return DEFAULT_PENDING_USERS_FOR_PROCESSING;
    }
}

/** {@inheritDoc } */
@Override
public synchronized void setPendingUsersForProcessing(int pendingUsersForProcessing) {
    doPut(PENDING_USERS_FOR_PROCESSING, String.valueOf(pendingUsersForProcessing));
    LOG.info("Number of Pending Users For Processing is set to : " + pendingUsersForProcessing);
}

我尝试更新属性的代码:

int pendingUsers = appProperties.getPendingUsersForProcessing();
int requestUsers = request.getUserKeys().size();
appProperties.setPendingUsersForProcessing(pendingUsers + requestUsers);
安德烈·沃尔金(Andrei Volgin)

这并非完全是线程问题,因为您可能有多个应用程序实例在执行任务,而这些实例彼此之间并不了解。因此,这是一个争用情况。

您有几种解决方法。

  1. 对您的计数器使用分片

  2. 无需不断更新同一实体,而是使用任务完成的时间作为ID,为每个已完成的任务创建一个新的实体。这种方法的优势在于,它创建了一个审计跟踪,并且您始终可以获取统计信息,例如今天,过去一个小时内完成的任务数等。要计算实体数,可以使用仅键查询,即几乎免费而且非常快。缺点是编写这些实体的成本较高-如果要完成的任务很多,这不是解决方案。

  3. 不用计算任务,而是计算这些任务的结果。例如,如果任务更新了用户状态,则可以使用免费且快速的仅键查询来计算处于“待定”状态的用户数。如果您已经拥有一个索引属性,可以将其用作标记来计算已完成任务的数量,那么这是一种非常好的方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Google App Engine中的数据存储区与Cloud SQL

来自分类Dev

Google App Engine数据存储区查询返回陈旧数据

来自分类Dev

Google App Engine(Python)-数据存储区正在复制实体

来自分类Dev

Google App Engine数据存储区的大表是如何设计的?

来自分类Dev

Google App Engine数据存储区-密钥与标识符

来自分类Dev

Google App Engine NDB数据存储区的简单说明

来自分类Dev

查询所有实体的Google App Engine数据存储区

来自分类Dev

在Google App Engine上运行数据存储区查询

来自分类Dev

Google App Engine数据存储区按属性删除实体

来自分类Dev

Google App Engine数据存储区获得财产的价值

来自分类Dev

Google App Engine数据存储区如何获取Key <?>的实体

来自分类Dev

在Google App Engine数据存储区上执行大型查询

来自分类Dev

Google App Engine数据存储区非复合索引

来自分类Dev

如何使用Java从Google App Engine数据存储区中的实体提取属性

来自分类Dev

在Google App Engine中,如何在更新SDK之后使开发数据存储区保持可用状态?

来自分类Dev

如何在Google App Engine数据存储区中添加动态属性

来自分类Dev

如何从Google App Engine(Java)数据存储区中的子实体查询父实体?

来自分类Dev

在Google App Engine数据存储区中搜索以前缀开头的字符串

来自分类Dev

覆盖Google App Engine- Java中的数据存储区实体

来自分类Dev

列出Google App Engine数据存储区中的所有实体时出现AttributeError

来自分类Dev

Google App Engine数据存储区关键字段中的“ name =“代表什么?

来自分类Dev

Google App Engine数据存储区中的索引和索引条目限制

来自分类Dev

计算在Google App Engine数据存储区中占得分和日期的索引

来自分类Dev

如何在Google App Engine数据存储区中存储来自Android的用户特定数据。祖先与否?

来自分类Dev

如何在Google App Engine数据存储区中存储来自Android的用户特定数据。祖先与否?

来自分类Dev

如何在后端而不是App Engine数据存储区中创建与Google Cloud SQL连接的Android应用程序?

来自分类Dev

对Google App Engine数据存储区中的所有用户使用相同的父密钥进行写交易是否合理?

来自分类Dev

IN查询Google App Engine数据存储区Java,其优先级基于列表中匹配关键字的数量

来自分类Dev

Go中的Google App Engine数据存储分片

Related 相关文章

  1. 1

    Google App Engine中的数据存储区与Cloud SQL

  2. 2

    Google App Engine数据存储区查询返回陈旧数据

  3. 3

    Google App Engine(Python)-数据存储区正在复制实体

  4. 4

    Google App Engine数据存储区的大表是如何设计的?

  5. 5

    Google App Engine数据存储区-密钥与标识符

  6. 6

    Google App Engine NDB数据存储区的简单说明

  7. 7

    查询所有实体的Google App Engine数据存储区

  8. 8

    在Google App Engine上运行数据存储区查询

  9. 9

    Google App Engine数据存储区按属性删除实体

  10. 10

    Google App Engine数据存储区获得财产的价值

  11. 11

    Google App Engine数据存储区如何获取Key <?>的实体

  12. 12

    在Google App Engine数据存储区上执行大型查询

  13. 13

    Google App Engine数据存储区非复合索引

  14. 14

    如何使用Java从Google App Engine数据存储区中的实体提取属性

  15. 15

    在Google App Engine中,如何在更新SDK之后使开发数据存储区保持可用状态?

  16. 16

    如何在Google App Engine数据存储区中添加动态属性

  17. 17

    如何从Google App Engine(Java)数据存储区中的子实体查询父实体?

  18. 18

    在Google App Engine数据存储区中搜索以前缀开头的字符串

  19. 19

    覆盖Google App Engine- Java中的数据存储区实体

  20. 20

    列出Google App Engine数据存储区中的所有实体时出现AttributeError

  21. 21

    Google App Engine数据存储区关键字段中的“ name =“代表什么?

  22. 22

    Google App Engine数据存储区中的索引和索引条目限制

  23. 23

    计算在Google App Engine数据存储区中占得分和日期的索引

  24. 24

    如何在Google App Engine数据存储区中存储来自Android的用户特定数据。祖先与否?

  25. 25

    如何在Google App Engine数据存储区中存储来自Android的用户特定数据。祖先与否?

  26. 26

    如何在后端而不是App Engine数据存储区中创建与Google Cloud SQL连接的Android应用程序?

  27. 27

    对Google App Engine数据存储区中的所有用户使用相同的父密钥进行写交易是否合理?

  28. 28

    IN查询Google App Engine数据存储区Java,其优先级基于列表中匹配关键字的数量

  29. 29

    Go中的Google App Engine数据存储分片

热门标签

归档