我在 Google App Engine 中遇到了争用问题,并尝试了解发生了什么。
我有一个带有注释的请求处理程序:
@ndb.transactional(xg=True, retries=5)
..在该代码中,我获取了一些东西,更新了其他一些东西等。但有时在请求期间日志中会出现这样的错误:
16:06:20.930 suspended generator _get_tasklet(context.py:329) raised TransactionFailedError(too much contention on these datastore entities. please try again. entity group key: app: "s~my-appname"
path <
Element {
type: "PlayerGameStates"
name: "hannes2"
}
>
)
16:06:20.930 suspended generator get(context.py:744) raised TransactionFailedError(too much contention on these datastore entities. please try again. entity group key: app: "s~my-appname"
path <
Element {
type: "PlayerGameStates"
name: "hannes2"
}
>
)
16:06:20.930 suspended generator get(context.py:744) raised TransactionFailedError(too much contention on these datastore entities. please try again. entity group key: app: "s~my-appname"
path <
Element {
type: "PlayerGameStates"
name: "hannes2"
}
>
)
16:06:20.936 suspended generator transaction(context.py:1004) raised TransactionFailedError(too much contention on these datastore entities. please try again. entity group key: app: "s~my-appname"
path <
Element {
type: "PlayerGameStates"
name: "hannes2"
}
>
)
..接着是堆栈跟踪。如果需要,我可以更新整个堆栈跟踪,但它有点长。
我不明白为什么会这样。查看我的代码中出现异常的行,我get_by_id
在一个完全不同的实体(Round)上运行。错误消息中提到的“PlayerGameStates”,名称“hannes2”是另一个实体 GameState 的父级,该实体已get_async
在前几行从数据库中 :ed;
# GameState is read by get_async
gamestate_future = GameState.get_by_id_async(id, ndb.Key('PlayerGameStates', player_key))
...
gamestate = gamestate_future.get_result()
...
奇怪(?)的事情是,该实体没有写入数据存储区。我的理解是,如果同一实体同时更新,可能会出现争用错误,并行..或者如果在短时间内发生太多写入..
但是在读取实体时也会发生这种情况吗?("suspended generator get.."??) 而且,这是否发生在 5 次 ndb.transaction 重试之后..?我在日志中看不到任何表明已进行任何重试的内容。
任何帮助是极大的赞赏。