Как использовать TSession Class BDE в Delphi?

Я использую несколько соединений с использованием ODBC. Во всем проекте я использую то же соединение, но создаю, использую и уничтожаю объект TQuery. Теперь я собираюсь использовать соединение в потоках и узнал, что Delphi BDE предоставляет TSession Class для этого. Я хочу знать, как использовать TSession для одновременной работы, пожалуйста, предоставьте пример кода для этого, если это возможно.

1 ответ

Хотя я согласен с тем, что BDE является старым, возможно создание поточно-ориентированного доступа к базе данных с использованием BDE и TSessions.

Учти это. Когда две копии одного и того же приложения работают одновременно, ядро ​​базы данных или сервер базы данных различают два экземпляра с целью блокировки записей и таблиц. Это различие возможно, потому что каждое приложение использует отдельное соединение или, в случае BDE, сеанс.

Сеанс представлен экземпляром TSession. В однопоточных проектах TSession создан для вас. Если вы хотите подключиться к BDE с двумя или более потоками, каждый из них должен иметь свою собственную TSession.

Использование нескольких сеансов TS продемонстрировано здесь, в этом действительно старом примере кода, который я выкопал (он старый, и я бы сделал это по-другому сегодня, но вы просили об этом). Хитрость заключается в том, что каждый сеанс должен иметь один и тот же сетевой каталог и иметь уникальный частный каталог. Вот потомок 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;

А вот и метод execute. Важно отметить, что для TSession.PrivateDir задано уникальное имя каталога (на основе ThreadID). Можно также использовать GUID или другое значение, если оно уникально. Также обратите внимание, что Session1 - это компонент TSession в модуле данных, а Query1 - это TQuery, который использует TDatabase (Database1), которая, в свою очередь, использует Session1. Session - это переменная, объявленная в модуле Bde.DBTables. Эта переменная ссылается на TSession по умолчанию, который BDE создает для TDataSets BDE, которые активны в основном потоке выполнения.

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;

Надеюсь, это поможет.

Другие вопросы по тегам