我正在使用ODBC进行多连接。在整个项目中我使用相同的连接,但创建,使用和destory TQuery对象。现在我将在线程中使用连接,并开始了解Delphi BDE为此提供TSession类。我想知道如何使用TSession进行并发操作,请尽可能提供代码示例。
答案 0 :(得分:14)
虽然我同意BDE是旧的,但可以使用BDE和TSessions创建对数据库的线程安全访问。
考虑一下。当同一个应用程序的两个副本同时运行时,数据库引擎或数据库服务器会区分这两个实例以进行记录和表锁定。这种区别是可能的,因为每个应用程序使用单独的连接,或者在BDE的情况下使用会话。
会话由TSession实例表示。在单线程项目中,TSession是为您创建的。如果要使用两个或多个线程连接到BDE,每个线程都应该有自己的TSession。
这里演示了使用多个TSession,在我挖出的这个非常古老的代码示例中(它已经很老了,我今天会做的不同,但是你要求它)。诀窍是每个会话需要具有相同的网络目录并具有唯一的私有目录。这是TThread的后代:
type
TWriteData = class(TThread)
private
FSQL: String;
FFileName: String;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; const SQL: String;
const FileName: String); override; overload;
end;
以下是重写的构造函数:
constructor TWriteData.Create(CreateSuspended: Boolean;
const SQL: String; const FileName: String);
begin
inherited Create(True);
FSQL := SQL;
FFileName := String;
end;
这是执行方法。重要的是,TSession.PrivateDir设置为唯一的目录名称(基于ThreadID)。也可以使用GUID或其他值,只要它是唯一的。另请注意,Session1是数据模块上的TSession组件,Query1是使用TDatabase(Database1)的TQuery,后者又使用Session1。 Session是Bde.DBTables单元中声明的变量。此变量引用BDE为在主执行线程中处于活动状态的BDE TDataSets创建的默认TSession。
procedure TWriteData.Execute;
var
DataMod: TDataModule1;
AppDir: String;
begin
AppDir := ExtractFilePath(Application.ExeName);
DataMod := TDataModule1.Create(nil);
try
with DataMod do
begin
//All sessions need a unique private directory
Session1.PrivateDir := AppDir + IntToStr(Self.ThreadID);
//All sessions share a common network control file
Session1.NetFileDir := Session.NetFileDir;
ForceDirectories(Session1.PrivateDir);
try
Query1.SQL.Text := FSQL;
ClientDataSet1.Open;
ClientDataSet1.SaveToFile(AppDir + FFileName);
ClientDataSet1.Close;
finally
SysUtils.RemoveDir(Session1.PrivateDir);
end; //try
end; //begin
finally
DataMod.Free;
end;
end;
我希望这会有所帮助。