Я использую несколько соединений с использованием ODBC. Во всем проекте я использую одно и то же соединение, но создаю, использую и уничтожаю объект TQuery. Теперь я собираюсь использовать соединение в потоках и узнал, что Delphi BDE предоставляет для этого класс TSession. Я хочу знать, как использовать TSession для одновременной работы, по возможности предоставьте образец кода для этого.
Как использовать класс TSession BDE в Delphi?
Ответы (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;
Надеюсь, это поможет.