2016-02-28 60 views
0

我在我的应用程序中有一个计数器,我期望有99%的时间在使用事务更新计数器时不会出现争用问题。GAE/P:为计数​​器使用延迟任务和事务

要处理1%的时候很热闹,我是通过使用交易延期任务中的思维更新计数器如下:

def update_counter(my_key): 
    deferred.defer(update_counter_transaction) 

@ndb.transactional 
def update_counter_transaction(my_key): 
    x = my_key.get() 
    x.n += 1 
    x.put() 

偶尔的情况下,当竞争导致交易失败,任务将被重试。

我熟悉分片计数器,但这看起来更容易,适合我的情况。

有什么我错过,可能会导致此解决方案无法正常工作?

回答

1

自动任务重试可能存在问题,至少在理论上可能会出于以外的原因预期计数器增量的交易排序。如果这种不需要的重试成功地重新执行计数器递增编码,计数器值可能会被丢弃(将高于预期值)。其中可能可能不是可以接受您的应用程序,具体取决于使用计数器。

这里是不需要的延迟执行任务的调用的例子:GAE deferred task retried due to "instance unavailable" despite having already succeeded

的这个问题的答案与本说明定期任务队列documentation似乎内嵌(我没有看到这样的音符the deferred task queues article,但我将其标记为可能我脑):

请注意,任务名称不提供绝对保证一次只有 语义。在极其罕见的情况下,多次调用创建相同名称的 任务可能会成功,但在此情况下,将只执行其中一个任务 。在例外的情况下, 可以运行多次。

从这个前瞻性它可能实际上是更好地保持计数器与相关的逻辑/事务操作的其余部分(如果有的话),而不是孤立它作为一个任务队列中的单独的事务一起递增。

+0

谢谢,对于我的应用程序来说,计数器并不确切,所以我不介意这种情况比较罕见。 –