Форум: "Базы";
Текущий архив: 2006.12.17;
Скачать: [xml.tar.bz2];
ВнизDBExpress, Синхронная запись Найти похожие ветки
← →
ildarkh (2006-10-09 17:11) [0]Здравствуйте, я достаю данные из одной БД(в данном случае Oracle), вставляю в другую(Interbase). Происходит это по запросу юзера или по таймеру. Возникает проблема, в случае малого интервала таймера или если юзер тыкается по кнопке "Обновить данные" - одни и те же данные пишутся по многу раз, так как, видимо, программа не ждет окончания записи в бд, а за запись отвечает сервер Interbase, т.е. получается рассинхронизация. Возможна ли остановка программы(она однопоточная), до тех пор, пока не будет произведена запись гарантированно? Причем желательно учесть случай, когда вместо Oracle и Interbase могут оказаться две любые, поддерживаемые DBExpress, базы данных?
Спасибо.
← →
Desdechado © (2006-10-09 20:05) [1]Юзер здесь лишнее звено. Его кнопка не должна быть активна, пока идет запись. Или, если очень нужно, вынеси чтение-запись фоновым потоком, а юзера посади читателем на основной поток.
Таймерное событие не должно вызывать чтение-запись, если еще не закончилось предыдущее, что легко отслеживается флагом.
← →
ildarkh (2006-10-11 12:40) [2]Каким образом можно определить окончание записи, если можно, то поконкретней пожалуйста.
← →
Desdechado © (2006-10-11 12:49) [3]Эскизно так:
в процедуре записи
flagDataHasBeenWritten:=False; // идет процесс записи
query.ExecSQL; // запись данных
flagDataHasBeenWritten:=True; // установка флага закончившейся записи
флаг можно проверять в другом месте, например, в событии таймера
← →
ildarkh (2006-10-11 13:14) [4]Проблема в следующем, вот даже на вашем примере. Сервер БД и моя программа это две разные программы, которым наплевать друг на друга, как они работают там.
После
query.ExecSQL; // запись данных
будет отправлен запрос на сервер БД, однако программа пойдет дальше, ничерта не ждет закончилась или нет запись в БД. Во всяком случае, это происходит с IBLocal.
Флаг ставить смысла нет, зачем он, подумайте сами, таймер не создает отдельного потока.
Например, могу аргументировать это, есть таблица, из нее выбираются 2000 записей со множеством полей. Для этого нажимаем на кнопку. Программа зависает на секунду, и все можно тыкать дальше на ту же. Повторяю, программа однопоточная. Открываю IBExpert с набранным запросом select count(*) from in_ticket - жму на Прогнать запрос, экран дает 200, ..., 300,...,400, ..., 2066 - идет запись...
← →
Desdechado © (2006-10-11 13:31) [5]> будет отправлен запрос на сервер БД, однако программа пойдет дальше,
> ничерта не ждет закончилась или нет запись в БД.
Пока выполнение команды СУБД не закончится, управление в программу не вернется.
Откуда ты свои странные сведения берешь?
> таймер не создает отдельного потока.
Но таймер вызывает событие, которое без проверки может вызвать конфликт при попытке записи в том же потоке, ибо библиотека gds32.dll не потокобезопасная. А если по событию таймера обнаружено состояние записи, лучше ждать следующего срабатывания таймера.
← →
Sergey13 © (2006-10-11 13:35) [6]> одни и те же данные пишутся по многу раз
А констрейнт поставить не судьба?
> будет отправлен запрос на сервер БД, однако программа пойдет
> дальше
Это вряд ли. Но если есть сомнения, то почему бы не закоммитить запись данных следующим оператором?
← →
ildarkh (2006-10-11 14:16) [7]
> > будет отправлен запрос на сервер БД, однако программа
> пойдет дальше,
> > ничерта не ждет закончилась или нет запись в БД.
> Пока выполнение команды СУБД не закончится, управление в
> программу не вернется.
> Откуда ты свои странные сведения берешь?
Выяснено экспериментально. Я еще раз цитирую себя
> есть таблица, из нее выбираются 2000 записей со множеством
> полей. Для этого нажимаем на кнопку. Программа зависает
> на секунду, и все можно тыкать дальше на ту же. Повторяю,
> программа однопоточная. Открываю IBExpert с набранным запросом
> select count(*) from in_ticket - жму на Прогнать запрос,
> экран дает 200, ..., 300,...,400, ..., 2066 - идет запись.
> ..
Чем вы это объясните?
← →
ildarkh (2006-10-11 14:18) [8]
> А констрейнт поставить не судьба?
Может быть требование не менять структуру таблицы. И это правильно, должен же быть способ узнавать, закончилась ли запись в результате запроса?
← →
Sergey13 © (2006-10-11 14:35) [9]> [8] ildarkh (11.10.06 14:18)
> Может быть требование не менять структуру таблицы
А при чем тут структура таблицы? Если в таблицу можно писать сколько угодно дублей, то зачем это контролировать. Например разные копии программы могут писать дубли - как ты в этом случае будешь действовать?
> И это правильно, должен же быть способ узнавать, закончилась
> ли запись в результате запроса?
Коммит прошел - закончилась.
← →
Desdechado © (2006-10-11 15:52) [10]> Я еще раз цитирую себя
ты лучше думай и слушай, а не самолюбуйся
> есть таблица, из нее выбираются 2000 записей со множеством
> полей. Для этого нажимаем на кнопку. Программа зависает
> на секунду, и все можно тыкать дальше на ту же.
Ну, выбрались они за эту секунду. Дальше ты повторяешь эту же самую выборку. В чем несоответствие ожиданиям?
> программа однопоточная. Открываю IBExpert с набранным запросом
> select count(*) from in_ticket - жму на Прогнать запрос,
> экран дает 200, ..., 300,...,400, ..., 2066 - идет запись.
> Чем вы это объясните?
Запрос
select count(*) from in_ticket
не может давать больше одно строки. И результат он всегда даст тот, который был на момент старта транзакции с этим запросом.
Повторный запрос может дать другой результат, если содержимое таблицы изменилось.
Но это ни в коей мере не показывает, что "ничерта не ждет закончилась или нет запись в БД". Видимо, у тебя каждая строка в своей транзакции пишется. А как и почему - это твоя тайна за 7 печатями..
← →
ANB © (2006-10-11 16:04) [11]
> > есть таблица, из нее выбираются 2000 записей со множеством
>
> > полей. Для этого нажимаем на кнопку. Программа зависает
>
> > на секунду, и все можно тыкать дальше на ту же. Повторяю,
>
> > программа однопоточная. Открываю IBExpert с набранным
> запросом
> > select count(*) from in_ticket - жму на Прогнать запрос,
>
> > экран дает 200, ..., 300,...,400, ..., 2066 - идет запись.
>
> > ..
>
> Чем вы это объясните?
Тем, что записи вставляются в цикле. И внутрь цикла воткнули Application.ProcessMessages;, чтобы программа не подвисала. А кнопку задисейблить забыли. Чудес не бывает.
← →
ANB © (2006-10-11 16:06) [12]Вообщето, многие компоненты доступа БД можно заставить работать асинхронно. Но тут уж надо знать способ узнавать, что выполнение завершено. Иначе - не фиг было включать такой режим.
← →
ildarkh (2006-10-11 16:08) [13]ANB, каюсь, ты прав...
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2006.12.17;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.049 c