我遇到了设计问题,我的应用程序有增长的流量,而且我有很多“交易冲突。正在重试......”。我不知道如何避免它们。
介绍: 此应用中的每位演员都可以访问另一位演员。
这是我的实际设计(它可能有错误,只是一个例子):
class Actor(object):
name = db.StringProperty()
class ActorVisits(object):
"""Store a list of all actors has visited the parent of this kind
Note: Has an ancestor an Actor
"""
visits = db.ListProperty(db.Key)
class Visit(object):
"""A new visit by actor on the parent of this kind.
Each time a same actor visits the parent of this kind, this kind is updated
with the new datetime for the visit.
Note: Has an ancestor an Actor
"""
actor = db.ReferenceProperty(collection_name=Actor)
visited_at = db.datetimeProperty()
这是一个用例的例子:
foo = Actor(name="foo")
bar = Actor(name="bar")
db.put([foo, bar])
def trx():
"""Store a new visite from 'bar' to 'foo' """
av = ActorVisits.get_bey_keys_name(key_name="v/foo", parent=foo)
if av is None:
av = ActorVisits(key_name="v/foo", parent=foo)
v = Visit.get_bey_keys_name(key_name="v/foo/bar", parent=foo, actor=bar)
if v is None:
v = Visit(key_name="v/foo/bar", parent=foo, actor=bar)
v.visited_at = datetime.datetime.utcnow()
async = db.put_async(v)
if not v.key() in av.visits:
av.visits.append(v.key())
av.put()
async.get_result()
db.run_in_transaction(trx, bar, foo)
如果有人想让我更好地使这个模型。感谢
答案 0 :(得分:2)
通过将Visits移出Actor的EntityGroup,使访问最终保持一致。如果每次访问都是根实体,则不会遇到任何写入速率问题,您可以轻松查询它们。
如果您不想创建大量的访问实体,只需更新一个实体,您可以通过将其基于Actor和访问者来确定访问确定性的关键字。
所以演员的Id为123, Vistor(另一位演员)拥有888的Id,
您创建了一个类型为Visit的键,其ID为“123_888”(无父级),您使用此键放置()访问,并更新时间,并覆盖之前的访问。你也可以在键上做一个get(),它会非常一致(如果你保持计数说)。
然后,您可以使用最终一致的查询构建ActorVisits。