Как использовать 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;
Надеюсь, это поможет.