对于一些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')',
'DELETE FROM TESTTABLE WHERE ID = 15');
我将准备一个命令对象堆栈(可能使用TObjectStack集合),一次调用一个命令的Execute方法,在执行一个命令时,我将FExecuted设置为True,并将组件保存到磁盘。
所以我要做的是运行所有的脚本,但是我想管理出问题的情况。
如果出了问题,我想执行从最后到第一个调用Undo方法的所有命令。当然,在执行此操作之前,我需要能够从磁盘还原组件(如果故障是硬件故障,如果故障是另一个原因,我已经在内存中有堆栈,我可以很容易地调用undo一次一个命令)。
注意:我不能依赖DB事务行为的主要原因是我还需要插入大的blob,并且每个blob都是从internet下载然后插入的,所以我不能让事务永远处于打开状态,因为我想将每个小更改提交给DB。我对blob做的是下载一个,插入它,下载下一个,插入它。。。
所以我的问题是:你能建议一种方法来持久化我的对象吗?我有Delphi2009,所以有一个选择是做一个TInterdacedPersistent并将组件保存到流,然后保存到文件中,无论如何,这样我会有很多文件,有额外的复杂性,而我更喜欢一个文件。你能建议一下吗?
编辑:我在Delphi2009中意识到TObjectStack有缺陷(Pop没有返回正确的类型),所以TObjectStack也可以这样做。