如何确保休眠版本号在 javascript 客户端中保持不变?

How to ensure that the hibernate version number stays immutable in a javascript client?

我有一个带 Java 和 Hibernate 的 Rest 后端,我使用 属性 版本的乐观锁定。 对于并发控制,此版本 属性 必须发送到客户端,然后使用 post 请求再次发送到服务器。 但是,在 javascript 客户端中,我无法控制此 属性 的完整性,例如:

记住这是一个 Rest 后端,因此我无法在服务器中保存交付给每个用户的对象的版本号,o 类似的东西。

那么,如果这是一个像我认为的那样有效的问题,我如何确保版本在客户端中保持不变?

使用将数字隐藏在只读后面的构造函数 getter:

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

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

或者,使用 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');    
};

这确实需要您的客户使用相对较新的浏览器。

就我个人而言,我会重新考虑这样做,因为我认为客户几乎没有这样做的动机,而且根据定义,您无法控制客户向您的 REST 服务发送的内容。

但是,如果您确实有业务案例,那么一个半解决方案是使版本 属性 成为 GUID。这样,您只有在拥有最新的 GUID 时才能提交,而客户端 B 没有,这会使版本控制情况更加复杂,因为在请求成功之前您不能只递增 1。

但是,即使在那里您也不是完全安全的,因为客户端 B 理论上可以执行单独的请求以从资源中获取更新的 GUID,然后使用更新的 GUID 重新提交失败的请求。

但是由于客户 B 可以对更新版本进行编辑以恢复客户 A 所做的并添加他们自己的,这与这样做本质上是一样的,并且由于他们有权这样做,我们回来了问问自己为什么我们首先再次担心那个案子。