|
|
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Доброе время суток форумчане. Есть такая проблема: есть основной поток – программа, и дополнительный поток обработки информации Дополнительный поток Код: pascal 1. 2. 3. 4. 5. Основной поток Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. когда был один поток – все работало. А когда я сделал несколько потоков, при добавлении новой записи, начали возникать ошибки (не на всех записях конечно): 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 отрабатывает нормально Заранее спасибо . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 17:53 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78, с одним коннектом можно работать только в одном потоке. "Распараллеливать" работу внутри коннекта нельзя. Даже если это можно с клиентом Firebird 2.5, никакой параллельности все равно не получится (потому что вызовы внутри коннекта сериализуются). кроме того, весьма подозрительно выглядит GetGenID. В процедуре той кроме gen_id что-то есть? Если нет, зачем тогда она нужна? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 18:25 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
kdv, - Я же думал, что не распараллеливаю внутри коннекта, т.к. "Insert", и "Post", я делаю в главном потоке, даже данные/файл (которые я обатываю в дополнительном потоке) не переношу (из потока в поток), а только приваиваю название записи конкретной обработке/файлу (в основном потоке), т.е. доп. поток обрабатывает файл и все, - Процедура "GetGenID" (TIBStoredProc), - работает с внутренней процедурой в БД, которая только генерирует ID ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 18:44 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78Процедура "GetGenID" (TIBStoredProc), - работает с внутренней процедурой в БД, которая только генерирует ID Дай угадаю: она это делает через select max(id)+1?.. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 19:02 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakov, не совсем так, в БД находится генератор, и внутренняя процедура Код: pascal 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 19:07 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78Дополнительный поток Основной поток С чего ты решил, что у тебя WORK_WITH_RECORD_DB() выполняется в основном потоке? Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 19:18 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakov, А TFMain .WORK_WITH_RECORD_DB() не о чем не говорит.. мне казалось, что в классе "ThPrepare" (который я объявил) выполняется дополнительный поток, а в классе "TFMain = class(TForm)" - основной ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 19:25 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78А TFMain.WORK_WITH_RECORD_DB() не о чем не говорит.. Да, лично мне это многое говорит. Но запомни, молодой: неявных вызовов Synchronize в Delphi не бывает. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 19:50 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakov, Да я о "Synchronize" читал, но там было сказано о объектах VCL. Поскольку в моем случае, такие объекты задействованы не были, то я решил "Synchronize" не использовать. Значит эти все (ошибки) вылазят из-за асинхронности потоков??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 20:57 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
в одном проекте потоки "короткие", и я создаю для себя пул коннектов к бд и выдаю потоку при старте в другом, там потоки долгие, создаю datamodule при старте и освобождаю вместе с потоком ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 21:07 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Но если это так, то тогда можно например в дополнительном потоке (при его запуске) создать например свой ibQuery, и общаться при помощи него с БД,а после окончания потока, например обновлять DataSet в основном потоке, чтоб пользователь мог видеть изменения в grid'е? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 21:27 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78там было сказано о объектах VCL. Поскольку в моем случае, такие объекты задействованы не были Да ну? А TFMain и ibdsMain это что такое? Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 21:29 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78не совсем так, в БД находится генератор, и внутренняя процедура нафиг эта процедура нужна как процедура? пиши уже select gen_id(.... а еще лучше - написать просто gen_id прямо в запросе insert. Ну ibdsmain переделать с датасета на IBQuery с insert, ибо датасет тут не уперся совершенно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 21:36 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78можно например в дополнительном потоке (при его запуске) создать например свой ibQueryможно, а также свой датабэйз и свой транзакшен. Konstantin-78обновлять DataSet в основном потоке, чтоб пользователь мог видеть измененияможно. коммит только сделать вовремя не забыть. kdvа еще лучше - написать просто gen_id прямо в запросе insert.дык это ж еще доку про кляузу ретурнинг читать, видимо зело трудно, проще пяток оберток над генератором нагородить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 21:58 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
kdvНу ibdsmain переделать с датасета на IBQuery с insert, ибо датасет тут не уперся совершенно. Да я "insert" я не правильно с помощью DataSet, делаю. Для таких ("автоматов") лучше IBQuery использовать. DataSet - у меня в общем (для отображения инф-ции ну или там запись поправить в grid'е). Я создам для доп.потока свой Query, чтоб не зависеть от разных потоков... и без всяких синхронизаций - если получится :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 22:03 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Иван, да выкинь ты этот потрат вообще отсюда, пусть с ним Рустам нянчится. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2015, 22:11 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Ivan_Pisarevskyдык это ж еще доку про кляузу ретурнинг читать Возможно, но если без returning, тогда хотя бы процедуру надо изничтожить. И все равно, в треде втыкание записи в датасет - это совсем нехорошо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 00:26 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78у меня в общем (для отображения инф-ции ну или там запись поправить в grid'е). если у тебя тут еще и гриды, то ты совсем какую-то замуть придумал - вставлять записи в тредах. Треды обычно используют в "автоматических" приложениях, которые пользователь не видит. Ну или для какой-то длительной обработки, которую нужно делать во время работы пользователя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 00:30 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
kdvа еще лучше - написать просто gen_id прямо в запросе insert.дык это ж еще доку про кляузу ретурнинг читать, видимо зело трудно, проще пяток оберток над генератором нагородить.[/quot] Это например: Код: sql 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 00:58 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
kdvесли у тебя тут еще и гриды, то ты совсем какую-то замуть придумал - вставлять записи в тредах. Треды обычно используют в "автоматических" приложениях, которые пользователь не видит. Ну или для какой-то длительной обработки, которую нужно делать во время работы пользователя. Не все норм.:-), dataset использует грид (в основном потоке), для отображения, обработанной инф-ции в доп. потоке, которую я буду вставлять с помощью дополнительного query (в доп. потоке), используя запрос, который я представил выше (с помощью "gen_id") и уже без использования внутренней процедуры ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 01:08 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78, Зачем тебе вообще еще один поток? Чего ты хочешь добиться-то? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 01:44 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
Konstantin-78dataset использует грид (в основном потоке), для отображения, обработанной инф-ции в доп. потоке ерунда какая-то. например, хоть в датасете, хоть в отдельном ibquery, все равно сначала должна пройти вставка (на сервер), и только потом - вставка в буфер датасета или перечитывание датасета. Никакой параллельности, совершенно. Даже если бы такие операции можно было бы делать параллельно, то с перечитыванием датасета, например, нет гарантии, что к этому моменту уже запись будет вставлена. А значит, перечитывание будет бесполезным. И придется втыкать синхронизацию, что убьет "параллелизм". Я советую поиграться с диаграммами состояний, в каком-нибудь case-инструменте. Чтобы при разработке алгоритмов было понятно, что может выполняться параллельно, а что нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 03:23 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
DarkMasterKonstantin-78, Зачем тебе вообще еще один поток? Чего ты хочешь добиться-то? Поток нужен мне для того, чтоб приложение не висло, когда обрабатываются данные, а если еще и в цикле, то вообще на часы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 15:34 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
kdv, Спасибо, за предложение. Что касается синхронизации, то я отказался от "synchronize", я работаю через "PostMessage". "synchronize" - убивает скорость обработки в 2 раза ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 15:40 |
|
||
|
Несколько потоков и работа с БД
|
|||
|---|---|---|---|
|
#18+
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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 16:37 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=38852417&tid=1563095]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
61ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 240ms |
| total: | 402ms |

| 0 / 0 |
