Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Несколько потоков и работа с БД / 25 сообщений из 29, страница 1 из 2
11.01.2015, 17:53
    #38851730
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Доброе время суток форумчане.
Есть такая проблема: есть основной поток – программа, и дополнительный поток обработки информации
Дополнительный поток
Код: pascal
1.
2.
3.
4.
5.
procedure ThPrepare.Execute;
begin
   //обработка инф-ции
   FMain.WORK_WITH_RECORD_DB(LConv_name);
End



Основной поток
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
procedure TFMain.WORK_WITH_RECORD_DB(AConv_name: string);
//работа с БД
begin
  ibdsMain.Insert;
  ibdsMain.FieldByNAme('ID').Value := GetGenID('SP_MAIN_ID');
   ibdsMain.FieldByNAme('PATH').Value := edPath.Text;
  ibdsMain.FieldByNAme('NATURAL_NAME').Value := ExtractFileName(PrFileOpen);
  …
  ibdsMain.Post;
end;

function TFMain.GetGenID(AStoredProcName: string): string;
//получение ID новой записи
var
begin
  ibspGetGenID.StoredProcName := AStoredProcName;
  ibspGetGenID.ExecProc;
  Result := ibspGetGenID.ParamByName('ID').AsString;
end;



когда был один поток – все работало.
А когда я сделал несколько потоков, при добавлении новой записи, начали возникать ошибки (не на всех записях конечно):
1. Project CF.exe raised exception class EIBInterBaseError with message 'violation of PRIMARY or UNIQUE KEY constraint "INTEG_2" on table "MAIN"'. Process stopped. Use Step or Run to continue.—

2.Project CF.exe raised exception class EDatabaseError with message “Field “ID” must have a value” Process stopped. Use Step or Run to continue.—
Я хочу знать, связаны ли эти ошибки с распараллеливанием процессов? И как от этой напасти избавиться можно?
Вторая ошибка возникает при "ibdsMain.Post;" - хотя функция получения ID отрабатывает нормально

Заранее спасибо .
...
Рейтинг: 0 / 0
11.01.2015, 18:25
    #38851737
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78,

с одним коннектом можно работать только в одном потоке. "Распараллеливать" работу внутри коннекта нельзя. Даже если это можно с клиентом Firebird 2.5, никакой параллельности все равно не получится (потому что вызовы внутри коннекта сериализуются).

кроме того, весьма подозрительно выглядит GetGenID. В процедуре той кроме gen_id что-то есть? Если нет, зачем тогда она нужна?
...
Рейтинг: 0 / 0
11.01.2015, 18:44
    #38851740
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
kdv,

- Я же думал, что не распараллеливаю внутри коннекта, т.к. "Insert", и "Post", я делаю в главном потоке, даже данные/файл (которые я обатываю в дополнительном потоке) не переношу (из потока в поток), а только приваиваю название записи конкретной обработке/файлу (в основном потоке), т.е. доп. поток обрабатывает файл и все,
- Процедура "GetGenID" (TIBStoredProc), - работает с внутренней процедурой в БД, которая только генерирует ID
...
Рейтинг: 0 / 0
11.01.2015, 19:02
    #38851746
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78Процедура "GetGenID" (TIBStoredProc), - работает с внутренней
процедурой в БД, которая только генерирует ID
Дай угадаю: она это делает через select max(id)+1?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.01.2015, 19:07
    #38851749
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Dimitry Sibiryakov,

не совсем так, в БД находится генератор, и внутренняя процедура
Код: pascal
1.
2.
3.
begin
  ID=gen_id(GEN_ID_MAIN, 1);
end
...
Рейтинг: 0 / 0
11.01.2015, 19:18
    #38851753
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78Дополнительный поток
Основной поток
С чего ты решил, что у тебя WORK_WITH_RECORD_DB() выполняется в основном потоке?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.01.2015, 19:25
    #38851757
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Dimitry Sibiryakov,

А TFMain .WORK_WITH_RECORD_DB() не о чем не говорит..
мне казалось, что в классе "ThPrepare" (который я объявил) выполняется дополнительный поток, а в классе "TFMain = class(TForm)" - основной
...
Рейтинг: 0 / 0
11.01.2015, 19:50
    #38851762
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78А TFMain.WORK_WITH_RECORD_DB() не о чем не говорит..
Да, лично мне это многое говорит. Но запомни, молодой: неявных вызовов Synchronize в
Delphi не бывает.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.01.2015, 20:57
    #38851787
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Dimitry Sibiryakov,

Да я о "Synchronize" читал, но там было сказано о объектах VCL. Поскольку в моем случае, такие объекты задействованы не были, то я решил "Synchronize" не использовать.
Значит эти все (ошибки) вылазят из-за асинхронности потоков???
...
Рейтинг: 0 / 0
11.01.2015, 21:07
    #38851788
krapotkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
в одном проекте потоки "короткие", и я создаю для себя пул коннектов к бд и выдаю потоку при старте
в другом, там потоки долгие, создаю datamodule при старте и освобождаю вместе с потоком
...
Рейтинг: 0 / 0
11.01.2015, 21:27
    #38851799
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Но если это так,
то тогда можно например в дополнительном потоке (при его запуске) создать например свой ibQuery, и общаться при помощи него с БД,а после окончания потока, например обновлять DataSet в основном потоке, чтоб пользователь мог видеть изменения в grid'е?
...
Рейтинг: 0 / 0
11.01.2015, 21:29
    #38851801
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78там было сказано о объектах VCL. Поскольку в моем случае, такие
объекты задействованы не были
Да ну? А TFMain и ibdsMain это что такое?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.01.2015, 21:36
    #38851803
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78не совсем так, в БД находится генератор, и внутренняя процедура
нафиг эта процедура нужна как процедура?
пиши уже select gen_id(....
а еще лучше - написать просто gen_id прямо в запросе insert. Ну ibdsmain переделать с датасета на IBQuery с insert, ибо датасет тут не уперся совершенно.
...
Рейтинг: 0 / 0
11.01.2015, 21:58
    #38851813
Ivan_Pisarevsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78можно например в дополнительном потоке (при его запуске) создать например свой ibQueryможно, а также свой датабэйз и свой транзакшен.
Konstantin-78обновлять DataSet в основном потоке, чтоб пользователь мог видеть измененияможно. коммит только сделать вовремя не забыть.
kdvа еще лучше - написать просто gen_id прямо в запросе insert.дык это ж еще доку про кляузу ретурнинг читать, видимо зело трудно, проще пяток оберток над генератором нагородить.
...
Рейтинг: 0 / 0
11.01.2015, 22:03
    #38851815
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
kdvНу ibdsmain переделать с датасета на IBQuery с insert, ибо датасет тут не уперся совершенно.

Да я "insert" я не правильно с помощью DataSet, делаю. Для таких ("автоматов") лучше IBQuery использовать.
DataSet - у меня в общем (для отображения инф-ции ну или там запись поправить в grid'е).

Я создам для доп.потока свой Query, чтоб не зависеть от разных потоков... и без всяких синхронизаций - если получится :-)
...
Рейтинг: 0 / 0
11.01.2015, 22:11
    #38851821
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Иван, да выкинь ты этот потрат вообще отсюда, пусть с ним Рустам нянчится.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
12.01.2015, 00:26
    #38851844
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Ivan_Pisarevskyдык это ж еще доку про кляузу ретурнинг читать
Возможно, но если без returning, тогда хотя бы процедуру надо изничтожить.
И все равно, в треде втыкание записи в датасет - это совсем нехорошо.
...
Рейтинг: 0 / 0
12.01.2015, 00:30
    #38851846
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78у меня в общем (для отображения инф-ции ну или там запись поправить в grid'е).
если у тебя тут еще и гриды, то ты совсем какую-то замуть придумал - вставлять записи в тредах. Треды обычно используют в "автоматических" приложениях, которые пользователь не видит. Ну или для какой-то длительной обработки, которую нужно делать во время работы пользователя.
...
Рейтинг: 0 / 0
12.01.2015, 00:58
    #38851849
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
kdvа еще лучше - написать просто gen_id прямо в запросе insert.дык это ж еще доку про кляузу ретурнинг читать, видимо зело трудно, проще пяток оберток над генератором нагородить.[/quot]

Это например:
Код: sql
1.
2.
3.
INSERT INTO  MAIN
(ID, NATURAL_NAME)
 VALUES (GEN_ID(ID, 1),'112')
...
Рейтинг: 0 / 0
12.01.2015, 01:08
    #38851852
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
kdvесли у тебя тут еще и гриды, то ты совсем какую-то замуть придумал - вставлять записи в тредах. Треды обычно используют в "автоматических" приложениях, которые пользователь не видит. Ну или для какой-то длительной обработки, которую нужно делать во время работы пользователя.
Не все норм.:-),
dataset использует грид (в основном потоке), для отображения, обработанной инф-ции в доп. потоке, которую я буду вставлять с помощью дополнительного query (в доп. потоке), используя запрос, который я представил выше (с помощью "gen_id") и уже без использования внутренней процедуры
...
Рейтинг: 0 / 0
12.01.2015, 01:44
    #38851854
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78,

Зачем тебе вообще еще один поток? Чего ты хочешь добиться-то?
...
Рейтинг: 0 / 0
12.01.2015, 03:23
    #38851861
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78dataset использует грид (в основном потоке), для отображения, обработанной инф-ции в доп. потоке

ерунда какая-то. например, хоть в датасете, хоть в отдельном ibquery, все равно сначала должна пройти вставка (на сервер), и только потом - вставка в буфер датасета или перечитывание датасета. Никакой параллельности, совершенно. Даже если бы такие операции можно было бы делать параллельно, то с перечитыванием датасета, например, нет гарантии, что к этому моменту уже запись будет вставлена. А значит, перечитывание будет бесполезным. И придется втыкать синхронизацию, что убьет "параллелизм".

Я советую поиграться с диаграммами состояний, в каком-нибудь case-инструменте. Чтобы при разработке алгоритмов было понятно, что может выполняться параллельно, а что нет.
...
Рейтинг: 0 / 0
12.01.2015, 15:34
    #38852349
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
DarkMasterKonstantin-78,

Зачем тебе вообще еще один поток? Чего ты хочешь добиться-то?
Поток нужен мне для того, чтоб приложение не висло, когда обрабатываются данные, а если еще и в цикле, то вообще на часы
...
Рейтинг: 0 / 0
12.01.2015, 15:40
    #38852357
Konstantin-78
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
kdv,

Спасибо, за предложение.
Что касается синхронизации, то я отказался от "synchronize", я работаю через "PostMessage".
"synchronize" - убивает скорость обработки в 2 раза
...
Рейтинг: 0 / 0
12.01.2015, 16:37
    #38852417
Ivan_Pisarevsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Несколько потоков и работа с БД
Konstantin-78Это например:
http://www.firebirdsql.org/refdocs/langrefupd21-insert.html

авторRETURNING clause

Available in: DSQL, PSQL

Added in: 2.0

Changed in: 2.1

Description: An INSERT statement adding at most one row may optionally include a RETURNING clause in order to return values from the inserted row. The clause, if present, need not contain all of the insert columns and may also contain other columns or expressions. The returned values reflect any changes that may have been made in BEFORE tiggers, but not those in AFTER triggers.

Examples:

insert into Scholars (firstname, lastname, address, phone, email)
values ('Henry', 'Higgins', '27A Wimpole Street', '3231212', null)
returning lastname, fullname, id

insert into Dumbbells (firstname, lastname, iq)
select fname, lname, iq from Friends order by iq rows 1
returning id, firstname, iq into :id, :fname, :iq;

Notes:

RETURNING is only supported for VALUES inserts and – since version 2.1 – singleton SELECT inserts.

In DSQL, a statement with a RETURNING clause always returns exactly one row. If no record was actually inserted, the fields in this row are all NULL. This behaviour may change in a later version of Firebird. In PSQL, if no row was inserted, nothing is returned, and the receiving variables keep their existing values.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Несколько потоков и работа с БД / 25 сообщений из 29, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]