2013-04-18 6 views
3

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

+0

BDE? в 2013 ? с Windows 8.1 рядом с выпуском? С поддержкой Embarcadero давно ушли? вы мачете шутите ... Найдите прямое соединение ODBC-соединения на Torry.net или переключитесь на что-то еще. UniDAC, FireDAC, DB-Express, ADO, ZeosDB, что угодно. Что касается тэгов, вы действительно используете Delphi 2009 до XE2, сразу 4 разных версии? –

+0

Нет, давайте не будем отмечать составленные версии. Если у вас есть определенная версия, которую вы хотите использовать, добавьте эту версию в качестве тега. –

+6

Wayback machine paging JohnKaster или MarkEdington ... – dthorpe

ответ

13

Хотя я согласен с тем, что 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. Эта переменная относится к TSGE по умолчанию, который BDE создает для BDE TDataSets, которые активны в основном потоке выполнения.

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; 

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

+2

Путь к работе, Кэри! :) –

+0

Спасибо Cary .. :) Я в настоящее время использую TDatabase для подключения к базе данных. Мы подключаемся при регистрации заявки и поддерживаем соединение до конца. Теперь код рефакторинга для mutithreading должен использовать TSession для подключения, а другой поток должен иметь свой собственный сеанс. Использование TSession. Должен ли я подключаться и отключаться каждый раз, когда мы используем базу данных. Как открыть базу данных в качестве общего подключения и выполнить параллельную операцию. – Ashu

+0

Каждый поток должен иметь свой собственный TSession, что означает, что каждый поток должен иметь отдельную TDatabase. Вы не можете открывать базу данных и совместно использовать ее одновременно, если вы не используете объект синхронизации, например, TCriticalSection, чтобы предотвратить одновременное обращение двух потоков к базе данных. Если вам нужен действительно одновременный доступ, вы должны использовать другой TSession и TDatabase для каждого потока.Если у вас нет ограничения на количество одновременных пользователей, вы можете открыть соединение (TSession и TDatabase) и использовать его для жизни потока. Пожалуйста, примите ответ, если это поможет. –

Смежные вопросы