Skip to main content

 

 

 

 

Template:OutSystems/Documentation_KB/Breadcrumb_New_Layout

 

 

Template:OutSystems/OSLanguageSwitcher

 

 

 

OutSystems

アプリケーションのデータレコードに対する同時更新の処理

同じプロセスに対して複数のユーザーが共同で作業を行っている場合、同じデータレコードを複数のユーザーが同時に更新する可能性があります。

ユーザーによる更新が互いに衝突することを防ぐには、同時更新をどのように処理すればよいでしょうか?

回答

この記事では、悲観的同時実行制御戦略を実装し、レコード保存時に更新の衝突を検出してユーザーが対処できるよう試みることで、この問題を解決する方法について説明しています。

他のトランザクションによるレコードへのアクセスを防ぐため、OutSystemsエンティティのGetForUpdateアクションを使用して更新中のレコードをロックすることができます。これによって同時実行を処理することができますが、他のユーザーによる更新を知らずにユーザーがレコードを上書きする可能性がまだ残っており、レコードの更新の衝突を処理する必要があります。

要求の処理方法の詳細については、「トランザクションの処理」をご覧ください。

他のユーザーからの同時更新によるデータの上書きを防ぐには、保存操作を制御するロジックを実装するという方法があります。

保存操作を制御する

Saveアクションフローを見てみると、レコードの作成や編集を行うロジックがすでに含まれていることがわかります。

元のSaveアクションフロー

このアクションに、自分がアクセスした後に更新が行われたかどうかを確認し、更新が行われていた場合は例外を発生させて保存操作をキャンセルする、新しいビジネスルールを追加します。

データレコードの保存操作を分離して別のアクションに抽象化すると、変更が簡単になり、入出力を変更せずに新しいビジネスルールを追加できるというメリットがあります。

そのためには、よく使用されるパターンである監査アトリビュート(CreatedBy、CreatedOn、UpdatedBy、UpdatedOnなど)を利用します。これらのアトリビュートを使用して、保存しようとしているレコードがデータベースへの最終アクセス以降に更新されたかどうかを確認することができます。

制御ロジックを追加した後のアクションは、以下のようになります。

Controlled Saveアクションフロー

1- 最初に、現在データベース内にあるレコードを取得し、レコードの更新をロックして、更新が終わるまで他のユーザーがレコードにアクセスできないようにします。同じレコードを編集するユーザーの数が多く、同時更新トランザクションが発生する可能性が高い場合、GetForUpdateエンティティアクションが特に重要です。

2- 次に、UpdatedOnアトリビュートと現在保存しようとしているレコードを比較し、レコードが更新されたかどうかを確認します。以下の条件を使用します。 GetSavedContact.List.Current.Contact.UpdatedOn > Contact.UpdatedOn

3- 同時更新が検出された場合は、User Exceptionを発生させ、このトランザクションでロールバックを実行します。同時更新が検出されなかった場合は、フローが通常のレコード更新に進み、監査フィールド(Updatedby、UpdatedOn)も更新します。 なお、この例ではコンテキストとして、レコードを更新したユーザーの情報も取得します。

強制更新

(ビジネス要件によって)一部のユースケースでは、手元にある情報が最新であることが確かな場合、強制更新を行うことがあります。

そのような場合はインターフェイスを少し変更して、入力した情報でデータベースを強制的に更新することができます。

すでに説明したように、同時実行による衝突がある場合はUser Exceptionを発生させます。次に、インターフェイスのユーザーアクションでこの例外をキャッチし、ユーザーがForce Updateオプションを選択できるようにします。

視覚的なフィードバックを提供する例外処理

Force Updateアクションは、同時実行の検証より以前にあった、Contactを更新する単純なサーバーアクションになります(監査フィールドを忘れないようにします)。

強制更新ロジック

サンプル

OutSystems Forgeで、実装に役立つサンプルアプリケーション - Concurrent Updates Sample - をダウンロードできます。上記のソリューションをテストには、以下の手順を実行します。

  1. 2つの異なるユーザー(ユーザーA - Amy PetersとユーザーB - Lawrence Ricci)がログインして、同じレコードにアクセスします。

  2. Amy Peters(ユーザーA)があるフィールドを編集し、変更を保存します。

    ユーザーAによる編集

  3. Lawrence Ricci(ユーザーB)があるフィールド(同じフィールドでも可)を編集し、変更の保存を試行します。衝突が検出されたことを示す警告メッセージが表示されます。

    ユーザーAによる編集直後のユーザーBによる編集

  4. Lawrence Ricci(ユーザーB)は、データを強制的に更新するか、変更をキャンセルしてユーザーAが保存したデータを保持するかを決定できます。

    ユーザーBによる強制更新