我正在使用 ODBC 进行多重连接。在整个项目中,我使用相同的连接,但创建、使用和销毁 TQuery 对象。现在我将在线程中使用连接,并了解到 Delphi BDE 为此提供了 TSession 类。我想知道如何使用 TSession 进行并发操作,如果可能,请提供代码示例。
1 回答
虽然我同意 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 TDataSet 创建的默认 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;
我希望这有帮助。