google 端点和 Objectify 中的线程安全以及 allocateId 是如何工作的?

Thread safety in google endpoints and Objectify and how does allocateId works ?

我有一个这种类型的 OfyService class

/**
 * Custom Objectify Service that this application should use.
 */
public class OfyService {
    /**
     * This static block ensure the entity registration.
     */
    static {
        factory().register(MerchantProfile.class);
        factory().register(Product.class); 
    }

    /**
     * Use this static method for getting the Objectify service object in order to make sure the
     * above static block is executed before using Objectify.
     * @return Objectify service object.
     */
    public static Objectify ofy() {
        return ObjectifyService.ofy();
    }

    /**
     * Use this static method for getting the Objectify service factory.
     * @return ObjectifyFactory.
     */
    public static ObjectifyFactory factory() {
        return ObjectifyService.factory();
    }
}

我在保存实体之前使用 factory().allocateId() 方法分配 Key(以获取 Long id)。我有一个问题,我需要将钱从一个帐户转移到另一个帐户并添加一个条目到交易 table。所以,我按以下方式使用 ofy().transact(new Work<~>)

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


            }
}

我在进入交易部分之前为交易分配了 Id,然后我从一个账户中减去钱,将其添加到另一个账户中,然后同时保存账户和交易实体。

我的顾虑如下

  1. 当有两个并发请求并且应用引擎实例为它们提供单独的请求处理程序并且为它们分配相同的 ID 时会发生什么,这取决于数据库状态,或者相同的 ID 不可能分配两次。
  2. 与我们在 Java 中用于制作临界区的传统同步块相比,Work 的控制流是什么?

PS:要在 Jersey(使用 JPA)等其他框架中执行相同的操作,我会使用同步块并在该块中完成事务。而且由于一次只有一个线程可以访问该块,并且一旦数据保存到 table 也会分配 id,所以不会有任何问题。

线程安全与数据存储或 JPA/RDBMSes 的数据一致性无关。如果你依赖同步,那你就做错了。

如果您创建一个完整的工作单元来执行您的任务并在事务中执行它,数据存储将确保它要么被完全应用,要么根本不被应用。它还将保证所有事务的行为就像它们是串行操作的一样。这可能会导致任何特定的执行中止并重试,但您不会以用户身份看到它。

简而言之:把它放在一个事务中,不用担心线程。