Многопоточный доступ к таблице

konvikkor
Дата: 01.06.2009 18:44:49
Помогите решить!
Блин мозг весь сломал! догнать немогу как правильно и красиво сделать!

Делаю доступ к таблице из патока все пучком но стоит только второму патоку сделать тожесамое то ппц база находится не врежиме редактирования или вноса инфы

Хелп!!! думаю сделать очередь но как правильно не доганю(((
Гаджимурадов Рустам
Дата: 01.06.2009 18:48:04
1. Что за таблица, что за компоненты доступа к данным?
2. Покажи свой код потока - обращения к таблице.
3. Старайся делать поменьше грамматических ошибок.
misha mike
Дата: 01.06.2009 18:49:10
konvikkor
Делаю доступ к таблице из патока все пучком но стоит только второму патоку сделать тожесамое то ппц база находится не врежиме редактирования или вноса инфы

Насколько мне не изменяет память, компоненты доступа к БД не потокобезопасны. Это значит что обращаться к их свойствам и методам может только тот поток, который их создал.
Warstone
Дата: 02.06.2009 13:05:15
misha mike
Насколько мне не изменяет память, компоненты доступа к БД не потокобезопасны. Это значит что обращаться к их свойствам и методам может только тот поток, который их создал.
Не совсем вроде... Достаточно в критическую секцию обернуть... Я так для Пг делал... Когда на куче вкладок выполняются запросы (на каждый запрос - свое подключение). Там было так: Кеш подключений. Если текущее подключение не используется, то при запросе (что-то типа EXECSQL) - в отдельном потоке начинается Open... Как только запрос открыт - к указанному датасорсу подрубается SQL набор. Ну и если у кого-то из пула подключений нет запроса более 5 минут, то оно(подключение) закрывалось. (max conections бережем)
misha mike
Дата: 02.06.2009 13:08:58
Warstone,
Согласен, но это все с умом делать нужно, новичку лучше просто создавать и пользовать компонент в контексте отдельного потока. Это и просто и безопасно, а с критическими секциями тоже можно здорово напортачить: дедлоки никто не отменял.
Зайцев Фёдор
Дата: 02.06.2009 13:57:53
misha mike
а с критическими секциями тоже можно здорово напортачить: дедлоки никто не отменял.

Так напортачить можно только специально )
Barmaley57
Дата: 02.06.2009 13:59:22
Если компоненты не потокобезопасны и их методы вызываются из разных потоков, то вполне можно обойтись synchronize'ом без всяких крит. секций и прочих объектов синхронизации, ибо synchonize как раз и испольщует крит. секцию...
_Vasilisk_
Дата: 02.06.2009 23:16:49
Barmaley57
synchonize как раз и испольщует крит. секцию...

Гаджимурадов Рустам
Дата: 02.06.2009 23:24:34
_Vasilisk_, а что не так? :)
Senya_L
Дата: 02.06.2009 23:28:55
Barmaley57
Если компоненты не потокобезопасны и их методы вызываются из разных потоков, то вполне можно обойтись synchronize'ом без всяких крит. секций и прочих объектов синхронизации, ибо synchonize как раз и испольщует крит. секцию...
Одними критическими секциями там не обошлось. Смотрим (линуксовые вставки убраны)
+
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False);
var
  SyncProc: TSyncProc;
  SyncProcPtr: PSyncProc;
begin
  if GetCurrentThreadID = MainThreadID then
    ASyncRec.FMethod
  else
  begin
    if QueueEvent then
      New(SyncProcPtr)
    else
      SyncProcPtr := @SyncProc;
    if not QueueEvent then
      SyncProcPtr.Signal := CreateEvent(nil, True, False, nil)
    else
      SyncProcPtr.Signal := 0;
    try
      EnterCriticalSection(ThreadLock);
      try
        SyncProcPtr.Queued := QueueEvent;
        if SyncList = nil then
          SyncList := TList.Create;
        SyncProcPtr.SyncRec := ASyncRec;
        SyncList.Add(SyncProcPtr);
        SignalSyncEvent;
        if Assigned(WakeMainThread) then
          WakeMainThread(SyncProcPtr.SyncRec.FThread);
        if not QueueEvent then
        begin
          LeaveCriticalSection(ThreadLock);
          try
            WaitForSingleObject(SyncProcPtr.Signal, INFINITE);
          finally
            EnterCriticalSection(ThreadLock);
          end;
        end;
      finally
        LeaveCriticalSection(ThreadLock);
      end;
    finally
      if not QueueEvent then
        CloseHandle(SyncProcPtr.Signal);
    end;
    if not QueueEvent and Assigned(ASyncRec.FSynchronizeException) then
      raise ASyncRec.FSynchronizeException;
  end;
end;
Видно используется WaitForSingleObject, а это означает синхронизацию с использованием объектов ядра.