【发布时间】:2012-11-09 19:38:17
【问题描述】:
我们有一个 db 模型,Vote,我们已经使用了一段时间,最近添加了一个 ndb 模型,Score,它代表一个实体的累积分数,基于它的投票。目前Score 是其投票的父节点,因为我们希望它们都在同一个实体组中(因此它们可以在同一个事务中更新)。我一直在尝试让一个可以更新Vote 和Score 的事务工作,但它始终失败。下面是一些示例代码:
def transaction():
score = self.key_score.get()
vote = db.get(self.key_vote)
# do stuff
score.put()
vote.put()
db.run_in_transaction(transaction)
据我所知(仅限开发服务器),这总是重试四次:
WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
ERROR
然后我收到“TransactionFailedError:无法提交事务。请重试。”。
我已经尝试了一些方法来解决这个问题:
更改gets 和puts 的顺序 - 我认为可能存在我不理解的实体组锁定问题,但切换gets 或puts 的顺序并没有改变行为。
-
异步放置。这实际上是我开始的 - 我所知道的同时放置一个 db 和一个 ndb 模型的唯一方法(我认为这本质上是在幕后放置多个键所做的)。结果一样。
score_future = score.put_async() vote_future = db.put_async(vote) score_future.get_result() vote_future.get_result() 将
db.run_in_transaction替换为ndb.transaction。这会在db.get上引发“AttributeError:'Key' 对象没有属性'reference'”。我不确定这里发生了什么 - 看起来一些幕后代码正在获得db.Key它期望ndb.Key。
有趣的是,如果我删除 parent 关系,我可以运行与上面相同的代码,这意味着实体不在同一个实体组中。
那么,是否可以在同一个实体组中同时拥有 db 和 ndb 模型?也许有一种简单的方法可以将 db 模型作为 ndb 或反之亦然?
【问题讨论】:
标签: google-app-engine app-engine-ndb