更新内容の消失の防止

Objective

After completing this lesson, you will be able to eTag を使用したデータ損失からの保護

同時実行性制御

以下では、同時修正が同時に実行される場合にデータの整合性を確保するために CAP で提供されるオプションの概要を把握します。

CAP ランタイムでは、以下のビデオで説明されているように、多数の更新状況を回避するためのさまざまな方法がサポートされています。

オプティミスティックロック

最初に、ETag (エンティティタグ) に基づくオプティミスティックロックコンセプトについて説明します。モデルエンティティに対して ETag を有効にするには、エンティティ定義のエレメントに @odata.etag アノテーションを追加します。

この例では、マネージドアスペクトの modifiedAt エレメントが、Books エンティティと Authors エンティティの両方の ETag エレメントとして定義されています。これには annotate ディレクティブが使用されます。これにより、既存の定義にアノテーションを付けることができます。

注記

データレコードが更新されるたびにコンテンツが一意に変更される要素は、ETag エレメントとして適しています。したがって、事前定義された管理アスペクトの modifiedAt エレメントは適切な候補です。また、更新ごとに再計算される更新カウンタまたは UUID を使用することもできます。

ETag の概念は、エンティティ (この例では、ブックまたは著者のバージョン) の特定のバージョンを識別することです。これを使用して、以下の例で説明するように、ロックを使用せずにデータの整合性を確保することができます。

以下の要求によって特定の作成者が取得されるとします。これは、その作成者のデータを変更する必要があるためです。

Code Snippet
1
GET Authors(18f76942-bfb3-40c5-8300-f999f14e9cc2)

この要求では、作成者のバージョン (ETag エレメント modifiedAt の値) が ETag HTTP 応答ヘッダを介して自動的に返されます。以下に例を示します。

Code Snippet
1
ETag: W/"2024-03-15T11:30:48.069Z"

作成者に対して変更されたデータを書き戻すために、受信した ETag 値が対応する変更要求の If-Match HTTP ヘッダで以下のように使用されます。

Code Snippet
1234567
PUT Authors(18f76942-bfb3-40c5-8300-f999f14e9cc2) If-Match: W/"2024-03-15T11:30:48.069Z" Content-Type: application/json { ... }

その後、CAP によって modifiedAt エレメントのコンテンツが変更されているかどうかがチェックされます。そうでない場合は、作成者データがデータベースで変更され、modifiedAt ETag フィールドが更新されます。はいの場合、データの読込後に作成者が別の依頼によって変更されたことを意味します。そのため、CAP によって変更依頼が中止され、HTTP 応答に対してステータスコード 412 (前提条件失敗) が設定されます。応答本文には、以下のようなエラーが含まれています。

JSON
12345
"error": { "code": "412", "message": "Precondition Failed", "@Common.numericSeverity": 4 }

ペシミスティックロック

オプティミスティックロックにより、さまざまな要求による同時変更時にデータの整合性が確保されます。

一方、ペシミスティックロックによって、同時トランザクションによる同時変更時にデータ整合性が確保されます。ペシミスティックロックを使用すると、他のトランザクションがどのような方法でもデータを変更できないようにデータをロックできます。

CAP では、ペシミスティックロックのためにデータベースロックが利用されます。これにより、排他ロックと共有ロックが区別されます。

排他的にロックされたデータレコードは、他のトランザクションによる変更も読込もできません。排他ロックは、データレコードがデータベースから読み込まれるときに設定されます。CAP のクエリ API では、この目的のために forUpdate() メソッドが提供されます。

注記

クエリの構築と実行については、後で説明します。

共有ロックによって、並列トランザクションによる同時更新も防止されます。ただし、すべてのトランザクションでロックされたデータレコードを読み込むことができます。

共有ロックを設定するために、クエリ API には forShareLock() メソッドが用意されています。

取得したロック (排他ロックまたは共有ロック) は、現在のトランザクションの完了時 (コミットまたはロールバック) に解放されます。

注記

ペシミスティックロックは SQLite ではサポートされていません。

デモと演習:オプティミスティック同時制御の追加

注記

演習問題として、SAP Business Application Studio で、以下のデモのステップバイステップの手順を実行します。

演習の開始点として、前の演習問題 "入力チェックの実装" の結果が正常に完了した場合はそれを使用します。または、以下の GitHub リポジトリのブランチ 8_input_validation を開始点として使用することもできます。

https://github.com/SAP-samples/cap-development-learning-journey

シミュレーションの完全な実装は、GitHub リポジトリの 9_concurrency_control ブランチにあります。

リポジトリのコンテンツとその使用方法の詳細については、ここを参照してください。

オプティミスティック同時実行制御を追加する方法については、ビデオを視聴してください。