0

我们正在开发一款 IOS 游戏,并使用 google-app-engine 作为后端。用户可以通过点击建筑物来兑现游戏中的钱。用户以相当快的速度点击多个建筑物,这会导致同一对象(USER)和不同建筑物上的多个并发事务。

不幸的是,这意味着第 4-5 次点击超时,因为它失去了重试。这也意味着由于锁定,第 2 次到第 5 次点击非常慢。

我的第一个想法是将交易变成一个任务,但是在第二次调用该函数时,totalAmount 会出错,因为第一次调用还没有完成。

那么有什么好方法可以支持对同一实体进行多次快速更新吗?

       int retries = 5;
        while (retries > 0) {

            // Wrap everything into a transaction from here
            TransactionOptions options = TransactionOptions.Builder.withXG(true);
            Transaction txn = datastore.beginTransaction(options);

                try{
                    // Ok we got the template - now check against the 

                   // Update user... with money gained 
                   // Update Building...money withdrawn

                   //Do the transaction
                    datastore.put(txn, user.getEntity());
                    datastore.put(txn, building.getEntity());
                    txn.commit();

                    // do callback code...which returns TotalMoney

                    break;

                } catch (Exception e) {
                    if(retries > 0){
                        retries--;
                    }
                    else{
                   //fail code...
                } finally {
                    if (txn.isActive()) {
                        txn.rollback();
                    }
                }
            }
4

2 回答 2

3

为了一致性,您需要事务,为了响应,您应该使用后端:

  1. 使用后端实例将数据保存在内存中以便快速更新。

  2. 每当在后端更新数据时,也会启动一个任务并以事务方式更新 Datastore 中的实体。

于 2012-04-24T16:54:53.567 回答
1

一种可能性是不使用 XG 交易,或者根本不使用交易。相反,拥有一个事务日志会更有益,您可以在其中记录所有操作。这样,您可以让任务或后端应用事务日志的效果,这样如果事情失败,它们最终会变得一致。这将大大提高您的前端吞吐量,并且从长远来看将使客户服务更加容易。

要记住的一件事是关于更新实体组的一般经验法则:设计您的实体组,以便以 1/s 的速率更新它们。实际速率要高得多,但这是防止冲突和争用的好规则。

于 2012-04-24T20:12:35.633 回答