1

Java と Hibernate を使用した Rest バックエンドがあり、バージョン プロパティで楽観的ロックを使用しています。同時実行制御のために、このバージョン プロパティはクライアントに送信され、ポスト リクエストでサーバーに送信される必要があります。ただし、JavaScript クライアントでは、このプロパティの整合性を制御できなくなります。たとえば、次のようになります。

  • クライアント「A」がリソース 1 を要求します。
  • クライアント「B」が同じリソースを要求します。
  • サーバーはリソース 1 バージョン 1 で両方のクライアントに応答します (それぞれの応答で)
  • クライアント「A」はリソースを変更し、変更を保存するためにポストを作成します。
  • サーバーは POST リクエストを処理し、Hibernate はバージョン番号をチェックします。1 = 1 なので、リソースは変更されます。
  • クライアント B は JavaScript をいじり、バージョン プロパティを 2 に変更し、POST リクエストを行います。サーバーは POST リクエストを処理し、現在は 2 = 2 であるため、リソースが変更され、クライアント A によって行われた変更は失われます。

これは Rest バックエンドであることを忘れないでください。したがって、各ユーザーに配信されたオブジェクトのバージョン番号をサーバーに保存することはできません。

それで、これが私が思うような有効な質問である場合、クライアントでバージョンが不変であることをどのように保証できますか?

4

2 に答える 2

1

個人的には、これを行うことを再考します。クライアントがそれを行う動機はほとんどまたはまったくないと思います。定義上、クライアントが REST サービスに送信するものを制御することはできません。

ただし、実際にビジネス ケースがある場合、半解決策の 1 つはバージョン プロパティを GUID にすることです。そうすれば、クライアント B が持っていない最新の GUID を持っている場合にのみ送信できます。また、要求が成功するまで 1 ずつ増やすことができないため、バージョン管理のケースがより複雑になります。

ただし、クライアント B は理論的には別の要求を実行してリソースから更新された GUID を取得し、失敗した要求を更新された GUID で再送信する可能性があるため、完全に安全というわけではありません。

しかし、クライアント B は、クライアント A が行ったことを元に戻し、独自のものを追加するために、更新されたバージョンで編集を行うことができたので、これは本質的にそれを行うことと同じです。そもそもあの事件がまた気になる。

于 2015-04-30T17:31:20.647 に答える
0

読み取り専用ゲッターの背後に数値を隠すコンストラクターを使用します。

var MyObject = function(version) {
    var _version = version;

    this.getVersion = function() { return _version; }
}

または、変数を 1 回だけ設定できる getter と setter のペアを使用します。

var MyObject = function() {
    var self = this;

    var _tripwire = false;

    var _value = null;

    self.setValue = function(val) {
        if (_tripwire==false)
            _tripwire = true;
        else
            throw "Value is read-only";

        _value = val;
    };

    self.getValue = function() {
        return val;
    }
};

JSFiddle

どのように失敗させたいかによって、throw ステートメントを return に置き換えて、プロパティ セットを黙って食べることもできますが、API コードの場合、呼び出し元が非常に安全でないことを行った場合は、大声で誇らしげに死ぬ方がよいでしょう。

プロパティ スタイルのアクセス方法を好む場合は、プロパティ アクセサーを使用して同じデザイン パターンを実現することもできます。

function setOnceProp(o, name) {
    var _value = null;

    var _tripwire = false;

    Object.defineProperty(o, name, {
        get: function() { 
            return _value; 
        },
        set: function(newValue) { 
            if (_tripwire==false)
                _tripwire = true;
            else
                throw "Value is read-only";

            _value = newValue; 
        },
        enumerable: true  
    });    
}

var MyObject = function() {
    var self = this;

    setOnceProp(self, 'value');    
};

これには、クライアントが比較的新しいブラウザーを使用している必要があります。

于 2015-04-30T17:23:59.733 に答える