如何重试已中止的 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.
两个问题:
如果事务中止了,我是否必须重新运行从事务开始执行的所有语句才能重试?或者只是再次重试 commit()
就足够了吗?
如何在 Spanner 上重现中止的提交以验证我的重试逻辑是否正确?
中止的事务包括提交冲突。这意味着您在交易期间读取的数据可能不再有效,因此您的代码做出的所有决定 - 以及它试图写入的数据,可能基于无效数据......所以你必须 re-do 从什么时候开始交易开始。
为了具体化,请考虑读取计数器、将其加倍,然后将该计数器写回的代码。想象一下,您的代码读取 4 试图写入 8 但得到了 ABORT。重新启动事务后,该值现在可能是 5,因此尝试再次写入 8 是错误的。相反,您的代码必须从头开始才能计算出它需要写入 10。如果您的代码具有 side-effects.
,这将变得棘手
我推荐使用官方 Cloud Spanner 客户端库。他们有各种事务运行器抽象,可以对错误做出适当的反应,包括重试逻辑。
如果事务中止,则应重试整个事务。
Cloud Spanner 没有提供强制事务中止的直接方法。您可以设置两个事务来执行以下操作:
- 开始事务 T1
- 开始事务 T2
- T1 读取第 1 行
- T2 读取第 1 行
- T1 提交(写入第 1 行)将成功
- T2 提交(写入第 1 行)将中止
在 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.
两个问题:
如果事务中止了,我是否必须重新运行从事务开始执行的所有语句才能重试?或者只是再次重试
commit()
就足够了吗?如何在 Spanner 上重现中止的提交以验证我的重试逻辑是否正确?
中止的事务包括提交冲突。这意味着您在交易期间读取的数据可能不再有效,因此您的代码做出的所有决定 - 以及它试图写入的数据,可能基于无效数据......所以你必须 re-do 从什么时候开始交易开始。
为了具体化,请考虑读取计数器、将其加倍,然后将该计数器写回的代码。想象一下,您的代码读取 4 试图写入 8 但得到了 ABORT。重新启动事务后,该值现在可能是 5,因此尝试再次写入 8 是错误的。相反,您的代码必须从头开始才能计算出它需要写入 10。如果您的代码具有 side-effects.
,这将变得棘手我推荐使用官方 Cloud Spanner 客户端库。他们有各种事务运行器抽象,可以对错误做出适当的反应,包括重试逻辑。
如果事务中止,则应重试整个事务。
Cloud Spanner 没有提供强制事务中止的直接方法。您可以设置两个事务来执行以下操作:
- 开始事务 T1
- 开始事务 T2
- T1 读取第 1 行
- T2 读取第 1 行
- T1 提交(写入第 1 行)将成功
- T2 提交(写入第 1 行)将中止