KiiObject の更新

Kii Cloud では、KiiObject の更新方法を 2 つの観点から用意しています。1 つがフルアップデートと部分アップデート、もう 1 つが更新チェックの有無です。

更新処理では、これらの組み合わせで指定できますが、Kii Cloud SDK では、一部、実行するメリットがない組み合わせがあります。詳細は下記の 更新方法の組み合わせ で説明します。

安全な更新の観点としては、これ以外に、複数 KiiObject の更新中のエラーへの配慮が必要になる場合があります。詳細は トランザクション を参照してください。

フルアップデートと部分アップデート

フルアップデートと部分アップデートは、クライアントから送信されたキーと値のペアで、サーバー上の既存のキーと値のペアをどのように置き換えるか決める方法です。フルアップデートがクライアントの値による完全な置き換え、部分アップデートがサーバーの値とのマージを意味します。

フルアップデート

KiiObject を完全に上書きします。

今まで KiiObject に保存されていたキーと値のペアは全て破棄され、新しく指定されたキーと値のペアが KiiObject に保存されます。

部分アップデート

KiiObject を部分的にアップデートします。

KiiObject が保存するキーと値のペアのうち、新しく指定されたキーと値のペアのみが更新されます。それ以外のキーと値のペアは以前のまま保持されます。

部分アップデートでは、クラウド上の既存のキーは削除できない点に注意してください。既存の KiiObject からキーを完全に削除したい場合はフルアップデートを使用します。

この例は JSON が 1 階層の場合ですが、深い階層にあるフィールド同士もクライアントの値とサーバーの値をマージした結果が保存されます。

更新チェック

更新チェックは、「楽観的ロック(Optimistic lock)」として知られる手法を実現する機能です。

オブジェクトを更新するとき、クラウド上の KiiObject が、前回クライアントにダウンロードした状態から更新されている場合(更新日時が変わっている場合)、エラーにする機能です。更新チェックありで更新すると、複数のクライアントから同時に更新があったときにデータが失われる現象を防止できます。

Kii Cloud ではデータベースでよく使用される排他的ロックの機能は提供されていませんが、この機能をうまく使うことで同時更新の問題を回避することができます。

楽観的ロックの例

ここでは、例として、アプリケーションスコープの Bucket にゲームのハイスコアを記録する処理を考えます。この Bucket には、ハイスコアを記録した KiiObject が 1 件だけあり、クライアントから直接更新するものとします。次のようなロジックになるはずです。

  1. クラウドからハイスコアの KiiObject を取得

  2. 今回のゲームのスコアが、取得した KiiObject の highscore の値よりも高い場合は、今回のゲームのスコアでクラウドのデータを更新

ここで、クライアント A とクライアント B がほぼ同時にゲームを終え、既存のハイスコア 60 点を超えたとします。クライアント A が 87 点、クライアント B が 76 点を取ったとすると、最終的な期待動作はハイスコア 87 点を記録することになります。

このときの更新シナリオは以下のとおりです。

  1. クライアント A が既存の highscore=60 を取得

  2. クライアント B が既存の highscore=60 を取得

  3. クライアント A がローカルで新しい値 highscore=87 をセット

  4. クライアント B がローカルで新しい値 highscore=76 をセット

  5. クライアント A が新しい highscore=87 で更新

  6. クライアント B が新しい highscore=76 で更新

更新チェックを行わない場合:無条件で上書きする動きになるため、highscore は新しい値 76 で書き換えられます。結果としてクライアント A の更新は失われ、今回の例では不適切な動きになります。

更新チェックを行う場合:上書き時にクライアント側の _version=1 と、クラウド側の _version=2 が異なっているため、クライアント B からの更新はエラーとなります。モバイルアプリで再試行のロジックを実装しておけば、クライアント B はもう一度クラウドから KiiObject をダウンロードして、2 の処理からやり直すことができます。

ここでのハイスコアの更新例は更新チェックの機能を説明するためのものです。実際のアプリケーションではデータの重要度に応じて セキュリティ に記載の注意事項に対する配慮も必要です。

更新チェックを行うかどうかは、同時更新の可能性や重要度から判断します。更新チェックを行うと、この例で見たような問題を回避できますが、同時更新によるエラーや再試行のロジックを実装しなければならず、実装コストが増します。通常の利用方法では同時更新が起こらない場合や、たとえ起こっても問題が軽微である場合は、チェックを行わないモードを選択することもできます。

更新方法の組み合わせ

フルアップデート/部分アップデートと、更新チェックの有無は組み合わせて指定できます。更新方法の組み合わせと、クライアント SDK を使った実装に必要な処理を以下に示します。

更新チェックなし 更新チェックあり
フルアップデート フルアップデート(更新チェックなし)
  • 更新前に KiiObject を取得しても、しなくてもよい(最終的に更新後に必要なキーと値のペアのすべてをクライアント側で用意できればよい)。
  • 更新ではキーと値のペア全体を送信して、サーバーの値はすべて入れ替え。
フルアップデート(更新チェックあり)
  • 実行前に KiiObject の取得が必要(更新前に _version が必要であるため)。同時に、既存のキーと値のペアすべてをダウンロード。
  • 更新ではキーと値のペア全体を送信して、サーバーの値はすべて入れ替え。
部分アップデート 部分アップデート(更新チェックなし)
  • 更新前に KiiObject の取得はしない方がよい(差分だけ送信しないと部分アップデートにならない)
  • 更新ではクライアント側で用意した差分だけを送信して、サーバーの既存データとマージ。
部分アップデート(更新チェックあり)
  • 実行前に KiiObject の取得が必要(更新前に _version が必要であるため)。既存のキーと値のペアは破棄した方がよい(差分だけ送信しないと部分アップデートにならない)
  • 更新ではクライアント側で用意した差分だけを送信して、サーバーの既存データとマージ。