代码之家  ›  专栏  ›  技术社区  ›  UnDiUdin

实现获取事务行为的命令堆栈-Delphi

  •  0
  • UnDiUdin  · 技术社区  · 14 年前

    对于一些resason,我不能依赖DB事务行为,但我需要实现自己的事务系统。

    我正在尝试的方法是借助于命令模式(我的情况更复杂,这里我放了一个简化版本供讨论):

    type
      IMyCommand = interface(IInterface)
        procedure Execute();
        procedure Undo();
      end;
    
    type
      TSQLCommand = class (TInterfacedObject, IMyCommand)
      private
        FDBConnection: TDBConnection;
        FDBQuery: TDBQuery;
        FExecuteSQL: string;
        FUndoSQL: string;
        FExecuted: boolean; // set to True as the command has been executed
      public
        procedure Execute;
        procedure Undo;
        procedure Prepare(aExecuteSQL, aUndoSQL: string);
        constructor Create(aDBConnection: TDBConnection);
        destructor Destroy; override;
      end;
    

    准备的电话可能是:

    Prepare('INSERT INTO TESTTABLE (ID, DATA) VALUES (15, 'Hello')',// aExecuteSQL
    'DELETE FROM TESTTABLE WHERE ID = 15'); //aUndoSQL
    

    我将准备一个命令对象堆栈(可能使用TObjectStack集合),一次调用一个命令的Execute方法,在执行一个命令时,我将FExecuted设置为True,并将组件保存到磁盘。

    所以我要做的是运行所有的脚本,但是我想管理出问题的情况。

    如果出了问题,我想执行从最后到第一个调用Undo方法的所有命令。当然,在执行此操作之前,我需要能够从磁盘还原组件(如果故障是硬件故障,如果故障是另一个原因,我已经在内存中有堆栈,我可以很容易地调用undo一次一个命令)。

    注意:我不能依赖DB事务行为的主要原因是我还需要插入大的blob,并且每个blob都是从internet下载然后插入的,所以我不能让事务永远处于打开状态,因为我想将每个小更改提交给DB。我对blob做的是下载一个,插入它,下载下一个,插入它。。。

    所以我的问题是:你能建议一种方法来持久化我的对象吗?我有Delphi2009,所以有一个选择是做一个TInterdacedPersistent并将组件保存到流,然后保存到文件中,无论如何,这样我会有很多文件,有额外的复杂性,而我更喜欢一个文件。你能建议一下吗?

    编辑:我在Delphi2009中意识到TObjectStack有缺陷(Pop没有返回正确的类型),所以TObjectStack也可以这样做。

    1 回复  |  直到 14 年前
        1
  •  3
  •   ComputerSaysNo    14 年前

    我看不出比使用事务更好的方法,正如Andrei K.提到的,您的实现是不安全的,因此必须使用StartTransaction、Commit和Rollback!

    推荐文章