Hazelcast VersionedPortalble的用法

时间:2019-03-25 12:27:33

标签: hazelcast

我正在寻找Hazelcast中的可移植序列化。我特别对VersionedPortable接口感兴趣。我创建了一个场景,其中两个客户端具有相同类的不同版本:

//VERSION 1
public class Vehicle implements VersionedPortable {
    private final String type;

    public Vehicle() { this.type = ""; }
    public Vehicle(final String type) { this.type = type; }

    public void setType(final String type) { this.type = type; }
    public String getType () { return this.type; }

    public void writePortable(PortableWriter writer) throws IOException {
         writer.writeUTF("type", type);
    }

    public void readPortable(PortableReader reader) throws IOException {
         type = reader.readUTF("type");
    }

    public int getFactoryId() { return 1; }
    public int getClassId() { return 1; }
    public int getClassVersion () { return 1;}
}

//VERSION 2
public class Vehicle implements VersionedPortable {
    private final String type;
    private final int tyres;

    public Vehicle() { this.type = ""; this tyres = 0;}
    public Vehicle(final String type, final int tyres) { this.type = type; this.tyres = tyres; }

    public void setType(final String type) { this.type = type; }
    public String getType () { return this.type; }

    public void writePortable(PortableWriter writer) throws IOException {
         writer.writeUTF("type", type);
         writer.writeInt("tyres", tyres);
    }

    public void readPortable(PortableReader reader) throws IOException {
         type = reader.readUTF("type");
         tyres = reader.readInt("tyres");
    }

    public int getFactoryId() { return 1; }
    public int getClassId() { return 1; }
    public int getClassVersion () { return 2;}
}

在以下情况下,我使用了这两个类:

  • 带有V1的Hazelcast客户端会创建车辆并将其存储在IMap中:type = Porsche
  • 带有V2的Hazelcast客户端会更新车辆并将其存储在IMap中:tyres = 4
  • 带有V1的Hazelcast客户端会更新车辆并将其存储在IMap中:type = Audi
  • 带有V2的Hazelcast客户端读取车辆并将其打印到控制台:预期:奥迪,4;得到:奥迪,0

我的期望不对吗?我开始怀疑VersionedPortable不能满足我的期望(在单个IMap中支持读取和编写同一对象的不同版本)。

Github(第95行)上的某些代码和另一个SO-post(请参见第三个项目符号)上的代码似乎指向该方向。

1 个答案:

答案 0 :(得分:0)

您引用的另一篇文章也很正确-您的V1代码仅了解类型字段,因此,由V1完成的任何写入操作只会写入类型字段,而不会写入轮胎字段。由于您的V1对象不了解轮胎,因此不会保留在先前更新期间由V2代码在其中写入的值。

好消息是,您的V1代码可以读取由V2代码编写的对象,而无需进行任何修改。 (注意:经过修改以更正语句,V1可以读取V2编写的对象,我打错了打字并说成原文)

V2代码需要注意,只要V1客户端仍然是系统的一部分,就必须准备好查看在那里没有任何值的条目。找不到任何值时,设置要使用的默认值可能会很有用。

在某些情况下,您可能要强制执行一项限制,即阅读器检查正在读取的对象的版本,如果它来自更高版本的代码,则禁止更新该对象。这样,您可以确保您不会丢失来自较新代码的更新,也许会引发异常,从而导致用户看到警告或错误,表明他们没有运行最新的客户端代码,并且应进行更新以进行写入。访问请求的对象。