如何重试已中止的 Spanner 提交?

How to retry Spanner commits that were aborted?

Commit() 的 Spanner 文档中说:

Commit might return an ABORTED error. This can occur at any time; commonly, the cause is conflicts with concurrent transactions. However, it can also happen for a variety of other reasons. If Commit returns ABORTED, the caller should re-attempt the transaction from the beginning, re-using the same session.

https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.Spanner.Commit

两个问题:

  1. 如果事务中止了,我是否必须重新运行从事务开始执行的所有语句才能重试?或者只是再次重试 commit() 就足够了吗?

  2. 如何在 Spanner 上重现中止的提交以验证我的重试逻辑是否正确?

中止的事务包括提交冲突。这意味着您在交易期间读取的数据可能不再有效,因此您的代码做出的所有决定 - 以及它试图写入的数据,可能基于无效数据......所以你必须 re-do 从什么时候开始交易开始。

为了具体化,请考虑读取计数器、将其加倍,然后将该计数器写回的代码。想象一下,您的代码读取 4 试图写入 8 但得到了 ABORT。重新启动事务后,该值现在可能是 5,因此尝试再次写入 8 是错误的。相反,您的代码必须从头开始才能计算出它需要写入 10。如果您的代码具有 side-effects.

,这将变得棘手

我推荐使用官方 Cloud Spanner 客户端库。他们有各种事务运行器抽象,可以对错误做出适当的反应,包括重试逻辑。

  • 如果事务中止,则应重试整个事务。

  • Cloud Spanner 没有提供强制事务中止的直接方法。您可以设置两个事务来执行以下操作:

    1. 开始事务 T1
    2. 开始事务 T2
    3. T1 读取第 1 行
    4. T2 读取第 1 行
    5. T1 提交(写入第 1 行)将成功
    6. T2 提交(写入第 1 行)将中止