如何处理数据不一致? AS3 IExternalizable.readExternalData + sqlstatement.execute()

时间:2013-01-03 08:39:49

标签: actionscript-3 sqlite iexternalizable

我进行AS3 Air开发并使用SQLite在会话之间存储对象,AS3 Developer Guide以及AS3 SDK Reference中都有详细记录。

存储在数据库中的类实现了IExternalizable,以便可以使用BLOB存储和恢复实例。这很好,但我很难找到如何正确应对故障反序列化。在以下情况下会出现此问题:

  1. 对象序列化
  2. 保存对象
  3. 班级已更改且计划已更新
  4. 序列化数据不再匹配已保存的数据
  5. 我最初的方法是这样的:

    public class SampleClass implements IExternalizable
    {
        public static const version:int = 1; //increments upon program update
        public var idata:int;
    
        public function readExternal(data:IDataInput):void{
            if(version != data.readInt()) //check for corrupted data
                throw new IOError();
    
            idata = data.readInt();
        }
    
        public function writeExternal(data:IDataOutput):void{
            data.writeInt(version);
            data.writeInt(idata);
        }
    }
    

    在readExternal中抛出一个错误导致我的SQLStatement.execute()失败并且try..catch没用。

    我目前处理这个问题的想法:

    1. 在程序更新(ouch)时删除数据库中的所有数据
    2. 向类添加标志以指示错误的反序列化
    3. 使SQLStatement.execute()对抛出错误做出正确反应
    4. 1和2我知道怎么做,但两个都不漂亮。 3我找不到解决方案(还有?)

      其他想法或技术诀窍。

1 个答案:

答案 0 :(得分:2)

您好,这已在Adobe AIR 1.5 Cookbook中记录(9.13迁移ActionScript中的序列化更改)由Greg Jastrab提供,他建议使用名称空间进行版本更改,如下面的代码示例所示:

public class WeatherData implements IExternalizable {
    namespace wd1_0 = "WD1.0";
    namespace wd1_1 = "WD1.1";

    protected var version:String;
    public var date:Date;
    public var low:Number;
    public var high:Number;

    public function WeatherData() {
        version = "WD1.1";
        date = new Date();
        low = high = 0;
    }
    public function readExternal(input:IDataInput):void {
        version = input.readUTF();
        var ns:Namespace = new Namespace(version);
        ns::parse(input);
    }
    public function writeExternal(output:IDataOutput):void {
        output.writeUTF(version);
        output.writeObject(date);
        output.writeFloat(low);
        output.writeFloat(high);
    }
    wd1_0 function parse(input:IDataInput):void {
        date = input.readObject() as Date;
        high = input.readFloat();
    }
    wd1_1 function parse(input:IDataInput):void {
        date = input.readObject() as Date;
        low = input.readFloat();
        high = input.readFloat();
    }
}

我已经使用过这个解决方案,它可以像承诺的那样运行:)以下是在未来版本中添加新成员的“算法”

  1. 添加新变量
  2. 修改writeExternal以将其包含在序列化
  3. 构造函数中的增量版本字符串
  4. 为新版本添加新名称空间
  5. 添加一个作用于新命名空间的解析函数,并实现readExternal以匹配修改后的writeExternal
  6. 最好的问候