Microsoft Dataverseでは、ETag と呼ばれる標準の HTTP リソースバージョン管理メカニズムを使用する条件付き操作がサポートされます。 Web API を使用して条件付き操作を使用して、レコードの取得を最適化し、アップサート操作を制限し、オプティミスティック コンカレンシーを適用して、他のユーザーによる変更の上書きを防ぎます。
ETag とリソースのバージョン管理
HTTP プロトコルは、リソースの特定のバージョンを識別するための エンティティ タグ (略して ETag ) を定義します。 ETag は、その正確な値は実装に依存する不透明な識別子です。 ETag 値は、強検証と弱検証の 2 種類で発生します。 厳密な検証は、対応する ETag 値が変更されていない場合、特定の URI で識別される一意のリソースがバイナリ レベルで同一であることを示します。 弱い検証では、リソース表現が同じ ETag 値に対して意味的に同等であることが保証されるだけです。
Dataverse では、すべてのエンティティ インスタンスに対して弱い検証用 @odata.etag プロパティが生成され、取得された各エンティティ レコードでこのプロパティが自動的に返されます。 詳細については、「 Web API を使用してテーブル行を取得する」を参照してください。
If-Match および If-None-Match ヘッダー
ETag 値を持つ If-Match ヘッダーと If-None-Match ヘッダーを使用して、リソースの現在のバージョンが最後に取得したバージョンと一致するか、以前のいずれかのバージョンと一致するか、またはどのバージョンとも一致しないかを確認します。 これらの比較は、条件付き操作のサポートの基礎を形成します。 Dataverse には、条件付き取得、オプティミスティック コンカレンシー、および限定されたアップサート操作をサポートする ETag が用意されています。
Warnung
クライアント コードでは、ETag の特定の値や、等しいか等しくないか以外の ETag 間の見かけ上の関係に意味を与えてはなりません。 たとえば、リソースのより新しいバージョンの ETag 値は、以前のバージョンの ETag 値より大きいとは限りません。 また、新しい ETag 値の生成に使用されるアルゴリズムは、サービスのリリース間で予告なく変更される可能性があります。
条件付き取得
Etag は、同じレコードに複数回アクセスするときにレコードの取得を最適化するのに役立ちます。 レコードを以前に取得した場合は、If-None-Match ヘッダーと共に ETag 値を渡して、前回取得時から変更がある場合のみデータを要求します。 データが変更された場合、要求は、要求の本文に最新のデータを含む 200 OK の HTTP 状態を返します。 データが変更されていない場合、要求は HTTP 状態コード 304 Not Modified を返して、レコードが変更されていないことを示します。
次のメッセージ ペアの例では、最後に取得してからデータが変更されておらず、Etag 値が 00000000-0000-0000-0000-000000000001 であったときに、W/"468026" が accountid と等しいアカウント レコードのデータを返します。
リクエスト:
GET [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001)?$select=accountcategorycode,accountnumber,creditonhold,createdon,numberofemployees,name,revenue HTTP/1.1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: W/"468026"
応答:
HTTP/1.1 304 Not Modified
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
以降のセクションでは、条件付き取得の使用に関する制限について説明します。
テーブルでオプティミスティック コンカレンシーが有効になっている必要がある
次の Web API 要求を使用して、テーブルでオプティミスティック コンカレンシーが有効になっているかどうかを確認します。 オプティミスティック コンカレンシーが有効になっているテーブルでは EntityMetadata.IsOptimisticConcurrencyEnabled プロパティが true に設定されています。 このURLを使用して値を取得してください:
GET [Organization URI]/api/data/v9.2/EntityDefinitions(LogicalName='<Entity Logical Name>')?$select=IsOptimisticConcurrencyEnabled
次の例では、連絡先テーブルから値を取得します。
リクエスト:
GET [Organization URI]/api/data/v9.2/EntityDefinitions(LogicalName='contact')?$select=IsOptimisticConcurrencyEnabled HTTP/1.1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
応答:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#EntityDefinitions(IsOptimisticConcurrencyEnabled)/$entity",
"MetadataId": "608861bc-50a4-4c5f-a02c-21fe1943e2cf",
"IsOptimisticConcurrencyEnabled": true
}
クエリに$expandを含めてはなりません
Etag は、取得している 1 つのレコードが変更されたかどうかのみ検出できます。 クエリで $expand を使用すると、より多くのレコードが返される可能性があり、それらのレコードのいずれかが変更されたかどうかを検出することはできません。 クエリに $expandが含まれている場合、要求は 304 Not Modifiedを返しません。
クエリに注釈を含めてはならない
GET要求に Prefer: odata.include-annotations ヘッダーを含めると、サーバーは304 Not Modifiedを返しません。 注釈の値は、関連するレコードの値を参照できます。 これらのレコードが変更された可能性があり、サーバーはこの変更を検出できないため、何も変更されていないことを示すのが正しくありません。
アップサート操作を制限する
アップサート操作では、レコードが存在しない場合にレコードが作成されます。それ以外の場合は、既存のレコードが更新されます。 ただし、ETag を使用してアップサートをさらに制限して、作成を防いだり、更新を防いだりすることはできます。
アップサートでの作成を禁止する
データを更新していて、レコードが意図的に削除された可能性がある場合は、レコードを再作成したくない場合があります。 この状態を回避するには、If-Match の値を持つ * ヘッダーをリクエストに追加します。
リクエスト:
PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
Content-Type: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
If-Match: *
{
"name": "Updated Sample Account ",
"creditonhold": true,
"address1_latitude": 47.639583,
"description": "This is the updated description of the sample account",
"revenue": 6000000,
"accountcategorycode": 2
}
応答:
サーバーでレコードが見つかると、ステータス 204 No Content の通常の応答が返されます。 サーバーがレコードを見つけられない場合は、状態 404 Not Foundで次の応答を受け取ります。
HTTP/1.1 404 Not Found
OData-Version: 4.0
Content-Type: application/json; odata.metadata=minimal
{
"error": {
"code": "",
"message": "account With Id = 00000000-0000-0000-0000-000000000001 Does Not Exist"
}
}
アップサートで更新を禁止する
データを挿入する場合、同じ id 値を持つレコードがシステムに既に存在している可能性があります。 この既存のレコードを更新したくない場合があります。 レコードの更新を防ぐには、値 "*" の If-None-Match ヘッダーをリクエストに追加します。
リクエスト:
PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
Content-Type: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: *
{
"name": "Updated Sample Account ",
"creditonhold": true,
"address1_latitude": 47.639583,
"description": "This is the updated description of the sample account",
"revenue": 6000000,
"accountcategorycode": 2
}
応答:
レコードが見つからない場合は、ステータス 204 No Content の通常の応答を受け取ります。 レコードが見つかった場合は、ステータス 412 Precondition Failed の次の応答を受け取ります。
HTTP/1.1 412 Precondition Failed
OData-Version: 4.0
Content-Type: application/json; odata.metadata=minimal
{
"error":{
"code":"",
"message":"A record with matching key values already exists."
}
}
オプティミスティック コンカレンシーを適用する
オプティミスティック コンカレンシーを使用して、最後にレコードを取得してからレコードが変更されたかどうかを検出します。 更新または削除する予定のレコードが取得後にサーバーで変更された場合は、更新または削除の操作を完了したくない場合があります。 次のパターンを使用すると、この状況を検出し、レコードの最新バージョンを取得し、必要な条件を適用して、操作を再試行するかどうかを再評価できます。
削除時にオプティミスティック コンカレンシーを適用する
accountid ヘッダーで送信された ETag 値が現在の値と異なるため、If-Match の 00000000-0000-0000-0000-000000000001 を持つアカウントに対する次の削除要求は失敗します。 値が一致した場合は、204 No Content 状態を受け取ります。
リクエスト:
DELETE [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
If-Match: W/"470867"
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
応答:
HTTP/1.1 412 Precondition Failed
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
{
"error":{
"code":"","message":"The version of the existing record doesn't match the RowVersion property provided."
}
}
更新時にオプティミスティック コンカレンシーを適用する
accountid ヘッダーで送信された ETag 値が現在の値と異なるため、00000000-0000-0000-0000-000000000001のIf-Matchを持つアカウントに対する次の更新要求は失敗します。 値が一致した場合は、204 No Content ステータスを受け取ります。
リクエスト:
PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
If-Match: W/"470867"
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
{"name":"Updated Account Name"}
応答:
HTTP/1.1 412 Precondition Failed
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
{
"error":{
"code":"","message":"The version of the existing record doesn't match the RowVersion property provided."
}
}
こちらも参照ください
Web API の条件付き操作のサンプル (PowerShell)
Web API の条件付き操作のサンプル (C#)
Web API の条件付き操作のサンプル (クライアント側 JavaScript)
Web API を使用して演算を実行する
Http 要求を作成し、エラーを処理する