我只需要确认我做对了。
例如,如果我有一个带有字段X
的实体x
,并且在发送请求时我想要X.x++
。如果我只使用X = ofy().load().type(X.class).id(xId).get()
,那么我会进行一些计算,之后我会X.x++
并保存它。如果在计算过程中发布了另一个请求,我将收到不需要的行为。相反,如果我在事务中执行此操作,则第二个请求在完成之前将无法访问X
。
是这样吗?
很抱歉,如果这个问题有点不高兴。
谢谢, 丹
答案 0 :(得分:2)
是的,你做得对,但是当使用交易记住第一个完成胜利而其余的失败。另请参阅@Peter Knego关于它们如何工作的答案。
但如果第二个请求无法阅读,请不要担心。 你有2个选择:
就重试而言:
您可以安全地多次调用您的交易功能 不良副作用。如果无法做到这一点,您可以进行设置 retries = 0,但知道事务将在第一次失败 争用事件
示例:
@db.transactional(retries=10)
就最终的一致性而言:
您可以通过指定读取策略来选择不使用此保护 要求最终的一致性。随着最终的一致阅读 一个实体,您的应用获取当前已知的实体状态 阅读,无论是否仍有提交的更改 应用。通过最终一致的祖先查询,索引 用于查询的内容与读取索引的时间一致 从磁盘。换句话说,最终的一致性读取策略会导致 获取和查询的行为就好像它们不是当前的一部分 交易。在某些情况下,这可能会更快,因为操作会这样做 在返回之前不必等待提交的更改 结果。
示例:
@db.transactional()
def test():
game_version = db.get(
db.Key.from_path('GameVersion', 1),
read_policy=db.EVENTUAL_CONSISTENCY)
答案 1 :(得分:2)
不,GAE交易不做锁定,他们使用optimistic concurrency control。您将始终可以访问X
,但是当您尝试将其保存在第二个交易中时,它将失败并显示ConcurrentModificationException
。