

# 条件付き書き込みによるオブジェクトの上書きを防ぐ方法
<a name="conditional-writes"></a>

条件付き書き込みを使用することで、`WRITE` リクエストにヘッダーを追加して、Amazon S3 オペレーションの前提条件を指定できます。オブジェクトを条件付きで書き込むには、HTTP `If-None-Match` または `If-Match` ヘッダーを追加します。

`If-None-Match` ヘッダーは、バケットに既に同じキー名を持つオブジェクトがないことを検証することで、既存のデータの上書きを防ぎます。

または、`If-Match` ヘッダーを追加して、オブジェクトを書き込む前にオブジェクトのエンティティタグ (ETag) をチェックすることもできます。このヘッダーを使用すると、Amazon S3 は指定された ETag 値と S3 内のオブジェクトの ETag 値を比較します。ETag 値が一致しない場合、オペレーションは失敗となります。

バケット所有者は、バケットポリシーを使用して、アップロードされたオブジェクトに条件付き書き込みを強制できます。詳細については、「[Amazon S3 バケットに条件付き書き込みを強制する](conditional-writes-enforce.md)」を参照してください。

**注記**  
条件付き書き込みを使用するには、AWS Signature Version 4 を使用してリクエストに署名する必要があります。

**Topics**
+ [キー名に基づくオブジェクトの上書きを防ぐ方法](#conditional-write-key-names)
+ [オブジェクトが変更された場合に上書きを防ぐ方法](#conditional-write-etags)
+ [条件付き書き込みの動作](#conditional-error-response)
+ [条件付き書き込みシナリオ](#conditional-write-scenarios)
+ [Amazon S3 バケットに条件付き書き込みを強制する](conditional-writes-enforce.md)

## キー名に基づくオブジェクトの上書きを防ぐ方法
<a name="conditional-write-key-names"></a>

HTTP `If-None-Match` 条件付きヘッダーを使用すると、オブジェクトを作成したり送信先バケットにコピーしたりする前に、そのキー名に基づいて、指定されたバケットにオブジェクトが既に存在するかどうかを確認できます。

HTTP `If-None-Match` ヘッダーによる条件付き書き込みは、`WRITE` オペレーション中にオブジェクトの存在をチェックします。バケット内で同じキー名が見つかると、オペレーションは失敗します。HTTP `If-None-Match` ヘッダーがない場合、バージョン管理されていないバケットまたはバージョニングが停止されたバケットに同じキー名を持つオブジェクトをアップロードまたはコピーすると、オブジェクトは上書きされます。キー名を使用する方法の詳細については、「[Amazon S3 オブジェクトに命名する](object-keys.md)」を参照してください。

**注記**  
HTTP `If-None-Match` ヘッダーは、バージョンバケット内のオブジェクトの現在のバージョンにのみ適用されます。

HTTP `If-None-Match` ヘッダーによる条件付き書き込みを実行するには、`s3:PutObject` アクセス許可が必要です。これにより、呼び出し元はバケット内のオブジェクトの存在を確認できます。`If-None-Match` ヘッダーには \* (アスタリスク) 値が必要です。

`If-None-Match` ヘッダーは、次の API で使用できます。
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)

### AWS CLI を使用した条件付き Put
<a name="conditional-writes-putobject-CLI-key-names"></a>

次の `put-object` コマンド例は、キー名が `dir-1/my_images.tar.bz2` のオブジェクトに対して条件付き書き込みを実行しようとします。

```
aws s3api put-object --bucket {{amzn-s3-demo-bucket}} --key dir-1/my_images.tar.bz2 --body my_images.tar.bz2 --if-none-match "*"       
```

詳細については、**AWS CLI コマンドリファレンスの「[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html)」を参照してください。

AWS CLI の詳細については、「AWS Command Line Interface ユーザーガイド**」の「[AWS Command Line Interface とは](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」を参照してください。

### AWS CLI を使用した条件付き Copy
<a name="conditional-writes-copyobject-CLI-key-names"></a>

次の `copy-object` コマンド例は、キー名が `dir-1/my_images.tar.bz2` のオブジェクトに対する条件付き書き込みを使用して、オブジェクトを送信先バケットにコピーしようとします。

```
aws s3api copy-object --copy-source {{amzn-s3-demo-bucket}}/key --key dir-1/my_images.tar.bz2 --bucket {{amzn-s3-demo-bucket2}} --if-none-match "*"            
```

詳細については、**AWS CLI コマンドリファレンスの「[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html)」を参照してください。

AWS CLI の詳細については、「AWS Command Line Interface ユーザーガイド**」の「[AWS Command Line Interface とは](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」を参照してください。

### AWS CLI を使用した条件付きマルチパートアップロード
<a name="conditional-writes-mpu-complete-CLI-key-names"></a>

次の `complete-multipart-upload` コマンド例は、キー名が `dir-1/my_images.tar.bz2` のオブジェクトに対する条件付き書き込みを使用して、マルチパートアップロードを完了しようとします。この例では、file:// プレフィックスを使用して、この特定のマルチパートアップロードのためにアップロードされたすべてのパートをリストする `mpustruct` という名前のローカルフォルダ内のファイルから JSON 構造をロードします。

```
aws s3api complete-multipart-upload --multipart-upload file://mpustruct --bucket {{amzn-s3-demo-bucket}} --key dir-1/my_images.tar.bz2 --upload-id {{upload-id}}  --if-none-match "*"             
```

詳細については、**AWS CLI コマンドリファレンスの「[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html)」を参照してください。

AWS CLI の詳細については、「AWS Command Line Interface ユーザーガイド**」の「[AWS Command Line Interface とは](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」を参照してください。

## オブジェクトが変更された場合に上書きを防ぐ方法
<a name="conditional-write-etags"></a>

オブジェクトの ETag は、オブジェクトに固有の文字列であり、オブジェクトのコンテンツへの変更を反映します。`If-Match` ヘッダーを使用して、Amazon S3 バケット内のオブジェクトの ETag 値を、`WRITE` オペレーション中に指定した値と比較できます。ETag 値が一致しない場合、オペレーションは失敗となります。ETag の詳細については、「[Content-MD5 と ETag を使用して、アップロードされたオブジェクトを検証する](checking-object-integrity-upload.md#checking-object-integrity-etag-and-md5)」を参照してください。

HTTP `If-Match` ヘッダーによる条件付き書き込みを実行するには、`s3:PutObject` と `s3:GetObject` のアクセス許可が必要です。これにより、呼び出し元は ETag をチェックし、バケット内のオブジェクトの状態を確認できます。`If-Match` ヘッダーには、文字列としての ETag 値が必要です。

`If-Match` ヘッダーは、次の API で使用できます。
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)

### AWS CLI を使用した条件付き Put
<a name="conditional-writes-putobject-CLI-etags"></a>

次の `put-object` コマンド例は、指定された ETag 値 `6805f2cfc46c0f04559748bb039d69ae` を使用して条件付き書き込みを実行しようとします。

```
aws s3api put-object --bucket {{amzn-s3-demo-bucket}} --key dir-1/my_images.tar.bz2 --body my_images.tar.bz2 --if-match "{{6805f2cfc46c0f04559748bb039d69ae}}"         
```

詳細については、**AWS CLI コマンドリファレンスの「[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html)」を参照してください。

AWS CLI の詳細については、「AWS Command Line Interface ユーザーガイド**」の「[AWS Command Line Interface とは](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」を参照してください。

### AWS CLI を使用した条件付き Copy
<a name="conditional-writes-copyobject-CLI-etags"></a>

次の `copy-object` コマンド例は、指定された ETag 値 `6805f2cfc46c0f04559748bb039d69ae` を使用して条件付き書き込みを実行しようとします。

```
aws s3api copy-object --copy-source {{amzn-s3-demo-bucket}}/key --key dir-1/my_images.tar.bz2 --bucket {{amzn-s3-demo-bucket2}} --if-match "{{6805f2cfc46c0f04559748bb039d69ae}}"             
```

詳細については、**AWS CLI コマンドリファレンスの「[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html)」を参照してください。

AWS CLI の詳細については、「AWS Command Line Interface ユーザーガイド**」の「[AWS Command Line Interface とは](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」を参照してください。

### AWS CLI を使用した条件付きマルチパートアップロード
<a name="conditional-writes-mpu-complete-CLI-etags"></a>

次の `complete-multipart-upload` コマンド例は、指定された ETag 値 `6805f2cfc46c0f04559748bb039d69ae` を使用して条件付き書き込みによるマルチパートアップロードを完了しようとします。この例では、file:// プレフィックスを使用して、この特定のマルチパートアップロードのためにアップロードされたすべてのパートをリストする `mpustruct` という名前のローカルフォルダ内のファイルから JSON 構造をロードします。

```
aws s3api complete-multipart-upload --multipart-upload file://mpustruct --bucket {{amzn-s3-demo-bucket}} --key dir-1/my_images.tar.bz2 --upload-id {{upload-id}} --if-match "{{6805f2cfc46c0f04559748bb039d69ae}}"             
```

詳細については、**AWS CLI コマンドリファレンスの「[https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html)」を参照してください。

AWS CLI の詳細については、「AWS Command Line Interface ユーザーガイド**」の「[AWS Command Line Interface とは](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」を参照してください。

## 条件付き書き込みの動作
<a name="conditional-error-response"></a>

**`If-None-Match` ヘッダーを使用した条件付き書き込みまたはコピー**  
`If-None-Match` ヘッダーを使用した条件付き書き込みは、バケット内の既存のオブジェクトに対して評価を実行します。バケットに同じキー名を持つ既存のオブジェクトがない場合、書き込みオペレーションは成功し、`200 OK` レスポンスが返されます。既存のオブジェクトがある場合、書き込みオペレーションは失敗し、`412 Precondition Failed` レスポンスが返されます。  
バージョニングが有効なバケットでは、同じ名前の現在のオブジェクトバージョンが存在しない場合、または現在のオブジェクトバージョンに削除マーカーがある場合、書き込みオペレーションは成功します。それ以外の場合は、書き込みオペレーションは失敗して、`412 Precondition Failed` レスポンスを返します。  
同じオブジェクト名に対して複数の条件付き書き込みまたはコピーが発生すると、最初の書き込みオペレーションは成功します。その後、Amazon S3 は以降の書き込みを失敗として、`412 Precondition Failed` レスポンスを返します。  
同時リクエストが発生した場合、そのオブジェクトに対する条件付き書き込みオペレーションが完了する前に、そのオブジェクトへの削除リクエストが成功すると、`409 Conflict` レスポンスも受け取ることができます。`PutObject` で条件付き書き込みを使用する場合、`409 Conflict` エラーを受け取った後にアップロードが再試行される場合があります。`CompleteMultipartUpload` を使用する場合、`409 Conflict` エラーを受け取った後にオブジェクトを再度アップロードするには、`CreateMultipartUpload` を使用してマルチパートアップロード全体を再開する必要があります。

**`If-Match` ヘッダーを使用した条件付き書き込みまたはコピー**  
`If-Match` ヘッダーは、バケット内の既存のオブジェクトに対して評価されます。同じキー名を持ち、ETag が一致する既存のオブジェクトがある場合、書き込みオペレーションは成功し、`200 OK` レスポンスが返されます。ETag が一致しない場合、書き込みオペレーションは `412 Precondition Failed` レスポンスで失敗します。  
同時リクエストの場合には `409 Conflict` レスポンスを受け取ることもできます。  
オブジェクトに対する条件付き書き込みオペレーションが完了する前にそのオブジェクトへの削除リクエストが成功すると、オブジェクトキーが存在しなくなるため、`404 Not Found` を受け取ることになります。`404 Not Found` レスポンスを受け取ったら、オブジェクトを再アップロードする必要があります。  
同じ名前の現在のオブジェクトバージョンが存在しない場合、または現在のオブジェクトバージョンに削除マーカーがある場合、オペレーションは `404 Not Found` エラーで失敗します。

## 条件付き書き込みシナリオ
<a name="conditional-write-scenarios"></a>

2 つのクライアントが同じバケットでオペレーションを実行しているような、以下のシナリオについて考えてみましょう。

**マルチパートアップロード中の条件付き書き込み**  
実行中のマルチパートアップロードリクエストは完全には書き込まれていないため、条件付き書き込みでは考慮されません。クライアント 1 がマルチパートアップロードを使用してオブジェクトをアップロード中である、次の例を考えてみましょう。このマルチパートアップロード中、クライアント 2 は条件付き書き込みオペレーションを使用して同じオブジェクトの書き込みを正常に実行できます。その後、クライアント 1 が条件付き書き込みを使用してマルチパートアップロードを完了しようとすると、アップロードは失敗します。

**注記**  
このシナリオでは、`If-None-Match` と `If-Match` ヘッダーの両方に `412 Precondition Failed` レスポンスが返されます。

![同じキー名で項目を書き込む 2 つのクライアントの例。1 つは MPU の UploadPart、もう 1 つは PutObject と条件付き書き込み。その後に開始される CompleteMultipartUpload オペレーションは失敗する。](http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/images/conwrite_put_mpu.png)


**マルチパートアップロード中の同時削除**  
条件付き書き込みリクエストが完了する前に削除リクエストが正常に完了すると、Amazon S3 は書き込みオペレーションについて `409 Conflict` または `404 Not Found` レスポンスを返します。これは、先に開始された削除リクエストが条件付き書き込みオペレーションよりも優先されるためです。このような場合、新しいマルチパートアップロードを開始する必要があります。

**注記**  
このシナリオでは、`If-None-Match` ヘッダーに対する `409 Conflict` レスポンスと `If-Match` ヘッダーに対する `404 Not Found` レスポンスが生成されます。

![2 つのクライアントの例。1 つはマルチパートアップロードを使用し、もう 1 つはこの MPU 開始後に削除リクエストを送信する。この削除リクエストは、条件付き書き込みが開始される前に終了する。](http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/images/conwrite_delete_mpu.png)


**注記**  
ストレージコストを最小限に抑えるため、`AbortIncompleteMultipartUpload` アクションを使用して指定した日数が経過した後に不完全なマルチパートアップロードを削除するようにライフサイクルルールを設定することをお勧めします。不完全なマルチパートアップロードを削除するライフサイクルルールの作成の詳細については、「[不完全なマルチパートアップロードを中止するためのバケットライフサイクルポリシーの設定](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpu-abort-incomplete-mpu-lifecycle-config.html)」を参照してください。