在 DynamoDB 中处理并发更新的最佳实践
在分布式系统中,多个进程或用户可能会尝试同时修改相同的数据。如果没有并发控制,这些并发写入可能会导致更新丢失、数据不一致或争用情况。DynamoDB 提供了多种机制来帮助您管理并发访问和维护数据完整性。
注意
UpdateItem 等单独的写入操作是原子操作,无论并发度如何,都始终对项目的最新版本进行操作。当您的应用程序必须读取某个项目,然后根据读取的值将其写回时(读取-修改-写入周期),就需要使用锁定策略,因为其他进程可能会在读取和写入之间修改该项目。
处理并发更新的主要策略有两种:
-
乐观锁:假设冲突情况很少。此策略允许并发访问,并在写入时使用条件写入检测冲突。如果检测到冲突,则写入失败,应用程序可以重试。
-
悲观锁:假设很可能出现冲突。此策略在修改资源之前获取对资源的独占访问权限,以这种方式来防止并发访问。其他进程必须等待直至解锁。
下表汇总了 DynamoDB 中提供的方法:
| 方法 | 机制 | 适用于 |
|---|---|---|
| 乐观锁 | 版本属性 + 条件写入 | 争用率低,重试成本低 |
| 悲观锁(事务) | TransactWriteItems |
多项目原子性,争用率中等 |
| 悲观锁(锁客户端) | 带租约和检测信号的专用锁定表 | 长时间运行的工作流,分布式协调 |
选择并发控制策略
按照以下准则来为工作负载选择正确的方法:
- 在下列情况下,使用乐观锁:
-
很少出现冲突。
重试失败写入的成本较低。
一次更新一个项目。
- 在下列情况下,使用事务:
-
需要以原子方式更新多个项目。
需要跨项目或表的全有或全无语义。
需要在单个操作中将条件检查和写入操作结合起来。
- 在下列情况下,使用锁客户端:
-
需要跨分布式进程协调对外部资源的访问。
关键环节运行时间长,出现冲突时重试的成本很高。
需要自动锁定到期来处理进程故障。
注意
如果您使用 DynamoDB 全局表,请注意对于并发更新,全局表使用“以最后一次写入者为准”的协调策略。在需要跨区域时,使用版本号实施乐观锁将无法正常工作,因为在一个区域进行写入操作可能会覆盖另一个区域的并发写入而没有版本检查。使用全局表时,请将应用程序设计为在应用程序级处理冲突。