Ошибка при выполнении запроса из потока
Ошибка при выполнении запроса из потока
У меня имеется запрос, который выполняется в потоке который запускается по таймеру раз в 5 сек. Запрос в потоке выполняется быстро, но на всякий случай перед выполнением его таймер выключается, а затем в процедуре синхронизации включается снова.
Данный запрос просто читает информацию из БД, ничего не изменяя.
Поток использует отдельное подключение (не локальное естественно).
Поток я дописал в программу которая принимает данные с порта и записывает в БД. Она выполняет последовательные (по получению данных) запросы которые добавляют записи в одну таблицу. Эту программу я тестировал довольно долгое время и на максимальной скорости. После этого она работает более пол года и ни одного сбоя.
Так вот я добавил в нее поток и начались глюки... не постоянно, но нет нет так вылезет, раз в несколько часов.
Глюки такого рода:
MainForm.SPAEventInsS
Unsuccessful execution caused by a system error that precludes successful execution of subsequent statement.Error reading data from the conntction
(MainForm.SPAEventInsS - процедура записи данных в таблицу).
Такая же ошибка только с процедурой из потока возникает.
При запуске из Delphi перед этой ошибкой возникает еще и ошибка в которой говориться что транзакция не запущена, хотя я их в данной программе всегда явно запускаю и подтверждаю... их всего 2. Одна в самой программе, другая в потоке.
1. Что это за ошибка?
2. Почему ругается на транзакцию когда я ее запустил...
Данный запрос просто читает информацию из БД, ничего не изменяя.
Поток использует отдельное подключение (не локальное естественно).
Поток я дописал в программу которая принимает данные с порта и записывает в БД. Она выполняет последовательные (по получению данных) запросы которые добавляют записи в одну таблицу. Эту программу я тестировал довольно долгое время и на максимальной скорости. После этого она работает более пол года и ни одного сбоя.
Так вот я добавил в нее поток и начались глюки... не постоянно, но нет нет так вылезет, раз в несколько часов.
Глюки такого рода:
MainForm.SPAEventInsS
Unsuccessful execution caused by a system error that precludes successful execution of subsequent statement.Error reading data from the conntction
(MainForm.SPAEventInsS - процедура записи данных в таблицу).
Такая же ошибка только с процедурой из потока возникает.
При запуске из Delphi перед этой ошибкой возникает еще и ошибка в которой говориться что транзакция не запущена, хотя я их в данной программе всегда явно запускаю и подтверждаю... их всего 2. Одна в самой программе, другая в потоке.
1. Что это за ошибка?
2. Почему ругается на транзакцию когда я ее запустил...
http://www.ibase.ru/devinfo/ibx.htm. Раздел TIBDataSet.
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
И что там написано? У меня отдельное подключение на основную программу и на поток, подключения не локальные, я об этом в начале писал.CyberMax писал(а):Пардон, опечатался. Раздел TIBDatabase.
Поток создается по таймеру.
Синхронизация ничего не делает, только включает таймер обратно. Таймер при срабатывании отключается что бы не создать два потока одновременно.
Код потока:WildSery писал(а):"Я сделал классную вещь, завернул в поток и она перестала работать. Почему?"
А насчёт написать, как именно работаешь коннектом к базе, с транзакциями, в каком месте что делаешь? Можно с примером кусочков кода.
Иначе получаются мысли вслух.
Код: Выделить всё
type
TFIBQueryThread = class(TThread)
private
procedure Syn;
protected
procedure Execute; override;
public
constructor Create; virtual;
end;
constructor TFIBQueryThread.Create;
begin
inherited
Create(True);
FreeOnTerminate := True;
Resume;
end;
procedure TFIBQueryThread.Execute;
begin
try
MainForm.TrEr.StartTransaction;
MainForm.SpEJouErCheck.ExecProc;
MainForm.TrEr.Commit;
Synchronize(Syn);
except
MainForm.TrEr.Rollback;
end;
end;
procedure TFIBQueryThread.Syn;
begin
MainForm.TmEr.Enabled:=True;
end;
Код: Выделить всё
IF (EXISTS(SELECT * FROM EJER WHERE TS<'NOW')) THEN
BEGIN
END
Запускается все это добро таймером:
Код: Выделить всё
procedure TMainForm.TmErTimer(Sender: TObject);
begin
TmEr.Enabled:=False;
TFIBQueryThread.Create;
end;
Вот и все что я добавил в программу...
Если закоментировать TFIBQueryThread.Create; все будет прекрасно работать, так как поток никогда не выполниться и таймер собственно тоже больше не будет срабатывать.
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Да вроде не должны, я же это подключение и транзакцию только для потока и использую. Поток в синхранизации таймер включил и через 5 сек только таймер сработает...Dimitry Sibiryakov писал(а):Рановато ты таймер перезапускаешь...
Уверен что задействованными подключением и транзакцией никто больше не пользуется?
Сейчас заметил что если в Delphi установить точку останова на срабатывание таймера то на второй третьей сработке ошибка и вылазиет... т.е. практически сразу. А если в TFIBQueryThread.Execute; поставить точку останова, а со сработки таймера убрать и по F9 продолжать то не виснет...
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
А чем таймер плох?Dimitry Sibiryakov писал(а):Брось чудить с включением/отключением таймера. И вообще брось таймер. Делай как я сказал выше: постоянно спящий поток буди event-ом.
В том то и дело что event-ом не могу, этот поток по идее должен запихивать в БД данные если в ней никаких действий не происходит... т.е. с оборудования поступают данные, я их пишу в базу. При записи в базу в специальную таблицу заносяться записи указывающие в какой срок должен поступить очередной сигнал. Так вот если он не поступает то мне нужно вставить данные... что то типа "нет сигнала от датчика"... А если данные не поступают то собственно и в таблицу ничего не пишеться и event неоткуда создавать
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Таймер плох тем что может запустить два потока подряд, что, похоже, у тебя и происходит. И это было бы ничего, используй они (потоки) только "внутренние" ресурсы, но они же используют компоненты на форме...
Чудик, я говорю не про IB event, а про Win32 event. Есть такая штука удобная для межпоточного взаимодействия.
Чудик, я говорю не про IB event, а про Win32 event. Есть такая штука удобная для межпоточного взаимодействия.
Dimitry Sibiryakov писал(а):Таймер плох тем что может запустить два потока подряд, что, похоже, у тебя и происходит. И это было бы ничего, используй они (потоки) только "внутренние" ресурсы, но они же используют компоненты на форме...
Чудик, я говорю не про IB event, а про Win32 event. Есть такая штука удобная для межпоточного взаимодействия.
Так он же отключается пере созданием потока... и включается в синхронизации поток то завершается уже... по краайней мере 5 сек есть на последнюю операцию в потоке
Ну во всяком случае спасибо, попробую посмотреть в сторону Win32 event
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05