

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 Amazon DocumentDB 中可重试写入
<a name="retryable-writes"></a>

从引擎版本 8.0.2 开始，Amazon DocumentDB 支持可重试写入。当写入操作由于暂时性网络错误或主要选举而失败时，驱动程序可以自动重试该操作一次。Amazon DocumentDB 会对重试的写入进行重复数据消除，这样该操作最多只能应用一次，从而保持其阶乘性。

可重试写入需要支持可重试写入协议的 MongoDB-compatible 驱动程序。大多数当前 MongoDB-compatible 驱动程序默认启用可重试写入（`retryWrites=true`在连接字符串中）。如果您要从早期版本升级到引擎 8.0.2，则可以`retryWrites=false`从连接字符串中删除以启用此功能。

## 要求
<a name="retryable-writes-requirements"></a>

要使用可重试写入，必须满足以下要求：
+ 亚马逊 DocumentDB 引擎版本 8.0.2 或更高版本。
+ 支持可重试写入的 MongoDB-compatible 驱动程序。有关最低版本，请参阅驱动程序的文档。
+ 连接字符串必须包含`retryWrites=true`，或者驱动程序必须默认为可重试写入（大多数最新的驱动程序都包含可重试写入）。

## 支持的操作
<a name="retryable-writes-supported-operations"></a>

可重试写入适用于每次写入最多影响一个文档的写入操作。批量操作符合条件，因为批次中的每一次写入都要单独进行重复数据消除。

以下写入操作是可重试的：
+ `insertOne`
+ `insertMany`
+ `updateOne`
+ `deleteOne`
+ `findOneAndUpdate`
+ `findOneAndDelete`
+ `findOneAndReplace`
+ `bulkWrite`（由`insertOne``updateOne``deleteOne`、或`replaceOne`运算组成时）

对于`insertMany`和`bulkWrite`，批次中的每个文档都将单独删除重复数据。如果需要重试，则仅插入尚未应用的文档。

**注意**  
`commitTransaction``abortTransaction`并且也可以作为事务控制命令重试，而不是写入。事务内的单个写入不可重试。有关更多信息，请参阅 [限制](#retryable-writes-limitations)。

## 限制
<a name="retryable-writes-limitations"></a>

以下限制适用于 Amazon DocumentDB 中的可重试写入：
+ `updateMany`并且`deleteMany`不可重试。
+ 在多语句事务中写入不可重试。事务提交和中止操作可单独重试。
+ 文档必须包含一个用于可重试插入的`_id`字段。
+ 可重试写入仅在引擎版本 8.0.2 及更高版本上可用。在早期的引擎版本`retryWrites=false`中，设置连接字符串以避免错误。
+ 在使用查询计划器版本 1.0 的集群上，写入操作不可重试。
+ 对于`findOneAndUpdate``findOneAndDelete`、和返回大型文档的`findOneAndReplace`操作，可重试写入可能会增加写入延迟，因为完整的结果文档会被缓存以进行重复数据消除。如果写入性能至关重要且返回的文档很大，请考虑`retryWrites=false`为这些工作负载进行设置。

## 启用可重试写入
<a name="retryable-writes-enabling"></a>

要启用可重试写入，请在连接字符串`retryWrites=true`中添加：

```
mongodb://{{<username>}}:{{<password>}}@{{<cluster-endpoint>}}:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=true
```

如果您的驱动程序默认为`retryWrites=true`，则可以`retryWrites=false`从连接字符串中删除任何显式内容。

有关连接字符串的完整演练，请参阅[以编程方式连接到 Amazon DocumentDB](connect_programmatically.md)。

## 可重试写入的工作原理
<a name="retryable-writes-how-it-works"></a>

当您的应用程序使用发送写入操作时`retryWrites=true`，驱动程序会将逻辑会话 ID (`lsid`) 和事务号 (`txnNumber`) 附加到写入命令。亚马逊 DocumentDB 使用这些标识符对写入内容进行重复数据消除：
+ 在第一次尝试时，Amazon DocumentDB 会执行写入操作并缓存结果。
+ 如果驱动程序重试相同的写入（相同的`lsid`和`txnNumber`），Amazon DocumentDB 将返回缓存的结果，而不重新执行写入。
+ Amazon DocumentDB 允许在最初写入后的 60 分钟内重试。驱动程序立即重试，因此此窗口远远超过驱动程序所需的时间。

如果重试在初次写入后超过 60 分钟到达，Amazon DocumentDB 将不再为其缓存结果，而是将写入操作作为新操作运行。

## 错误处理
<a name="retryable-writes-errors"></a>

以下错误特定于 Amazon DocumentDB 中的可重试写入：


| 错误代码 | Name | 说明 | 
| --- | --- | --- | 
| 225 | TransactionTooOld | 已经为同一会话和语句提交了更新的交易号，因此此次重试已过时，无法应用。 | 
| 301 | 不支持可重试写入 | 写入包含可重试的写入字段，但引擎版本不支持可重试写入，或者该操作不可重试。连接到 8.0.2 之前的引擎版本retryWrites=false时设置。 | 

## 从 retryWrites=False 迁移
<a name="retryable-writes-migration"></a>

如果您正在升级到引擎版本 8.0.2 并且当前在连接字符串`retryWrites=false`中使用：

1. 将您的集群升级到引擎版本 8.0.2 或更高版本。

1. `retryWrites=false`从应用程序的连接字符串中删除，或将其更改为`retryWrites=true`。

1. 无需更改应用程序代码。驱动程序会自动处理重试。