0

我需要创建一个工具来针对数据库执行复杂的脚本。

出于几个原因,我不能依赖数据库事务行为,但我需要实现自己的事务系统。

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

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;

我创建了一组动作,对于每个动作,我都会传递一个“执行”和“撤消”的 sql 语句,示例:

对 Prepare 的调用可能是:

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

所以不知何故我做了非常小的改变(比如插入一个简单的行,更新一个行,......),对于每一个改变,“撤消”都是非常明显的。

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

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

如果出现问题,我想执行从最后到第一个调用 Undo 方法的所有命令。当然,在这样做之前,我需要能够从磁盘恢复组件(如果故障是硬件故障,如果故障是另一个原因,我已经在内存中拥有堆栈,我可以轻松地调用撤消一个命令时间)。

注意:我不能依赖数据库事务行为的主要原因是我还需要插入大 blob,每个 blob 都是从 Internet 下载然后插入的,所以我不能永远打开事务,因为我想提交每个对分贝的小改动。我对 blob 所做的是下载一个,插入它,下载下一个,插入它,...

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

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

4

1 回答 1

3

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

于 2010-11-08T20:11:37.013 回答