4

我正在使用 ODBC 进行多重连接。在整个项目中,我使用相同的连接,但创建、使用和销毁 TQuery 对象。现在我将在线程中使用连接,并了解到 Delphi BDE 为此提供了 TSession 类。我想知道如何使用 TSession 进行并发操作,如果可能,请提供代码示例。

4

1 回答 1

15

虽然我同意 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;

我希望这有帮助。

于 2013-04-18T17:52:17.273 回答