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

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


person Ashu    schedule 18.04.2013    source источник
comment
BDE? в 2013 ? с Windows 8.1 близкой к релизу? С поддержки Embarcadero давно отказались? Вы, наверное, шутите ... Найдите библиотеку для прямого подключения ODBC на Torry.net или переключитесь на что-нибудь другое. UniDAC, FireDAC, DB-Express, ADO, ZeosDB, что угодно. А что касается тегов, вы действительно используете Delphi 2009 до XE2, сразу 4 разных версии?   -  person Arioch 'The    schedule 18.04.2013
comment
Нет, не будем ставить метки выдуманными версиями. Если у вас есть конкретная версия, которую вы хотите использовать, добавьте эту версию как тег.   -  person David Heffernan    schedule 18.04.2013
comment
Аппарат обратного пейджинга пейджирует ДжонКастеру или Марку Эдингтону ...   -  person dthorpe    schedule 18.04.2013
comment
@Ashu - Серьезно, не используйте TQuery, TTable, TStoredProc, TDatabase или TSession.   -  person Nick Hodges    schedule 18.04.2013
comment
@Ashu Если вы считаете, что предоставленный ответ правильный, примите его как ответ   -  person Cary Jensen    schedule 21.05.2013


Ответы (1)


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

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

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

Использование нескольких TSessions демонстрируется здесь, в этом действительно старом примере кода, который я откопал (он старый, и сегодня я бы сделал это по-другому, но вы просили об этом). Хитрость в том, что у каждого сеанса должен быть один и тот же сетевой каталог и уникальный частный каталог. Вот потомок 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 - это TQuery, который использует TDatabase (Database1), который, в свою очередь, использует Session1. Сессия - это переменная, объявленная в модуле Bde.DBTables. Эта переменная относится к сеансу TSession по умолчанию, который BDE создает для наборов TDataSet 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;

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

person Cary Jensen    schedule 18.04.2013
comment
Спасибо, Кэри .. :) В настоящее время я использую TDatabase для подключения к базе данных. Подключаемся при запуске приложения и держим связь до конца. Теперь рефакторинг кода для многопоточности должен ли я использовать TSession для подключения, а другой поток должен иметь свой собственный сеанс. Использование TSession Должен ли я подключаться и отключаться каждый раз, когда мы используем базу данных. Как я могу открыть базу данных как общее соединение и выполнить параллельную операцию. - person Ashu; 23.04.2013
comment
У каждого потока должен быть свой собственный TSession, что означает, что каждый поток должен иметь отдельную TDatabase. Вы не можете открыть базу данных и совместно использовать ее одновременно, если вы не используете объект синхронизации, такой как TCriticalSection, для предотвращения одновременного доступа двух потоков к базе данных. Если вам нужен действительно одновременный доступ, вы должны использовать разные TSession и TDatabase для каждого потока. Если у вас нет ограничения на количество одновременных пользователей, вы можете открыть соединение (TSession и TDatabase) и использовать его в течение всей жизни потока. Примите ответ, если это поможет. - person Cary Jensen; 26.04.2013
comment
Другой вариант - использовать пул соединений. Я написал статью об использовании семафора для управления пулом соединений. Эта статья и образец пула подключений доступны в сети разработчиков Embarcadero (edn.embarcadero.com). Найдите мое имя и семафор или пул соединений. Хотя пул соединений позволяет использовать один и тот же набор соединений из нескольких потоков, он вводит новый набор собственных сложностей. Я бы придерживался создания нового соединения в каждом потоке, если вы не обнаружите, что накладные расходы на создание нового соединения для каждого потока являются проблемой. - person Cary Jensen; 26.04.2013