Страница 1 из 1

Отдельный Thread как отправка данных на сервер

Добавлено: 07 Декабрь 2015, 23:19
gopstop2007
Программа локальная, но с синхронизацией данных на удаленном сервере. Синхронизация происходила при входе программы или при запуске пользователем. Решил полностью автоматизировать данный процесс, хотелось бы узнать мнение тех кто уже нашел решение. Сам процесс:
1. Пользователь (add,change, delete) запись в ЛЮБОЮ таблицу БД и это действие записалось например в лог таблицу см. ниже

Код: Выделить всё

ThreadLogs  FILE,DRIVER('TOPSPEED'),NAME(FIL:ThreadLogsChangeSaveInet),PRE(TL),CREATE 
idRecKey          KEY(SavWC:idRec),PRIMARY,NOCASE,OPT
NameBDKey         KEY(SavWC:NameBD,SavWC:idOper),DUP,NOCASE
record            RECORD
idRec               LONG
NameBD              LONG	 !Название(номер) таблицы
idOper              BYTE		 !1insert 2change 3delete
idRecBD             ULONG	 ! Уникальный код записи 
Used                BYTE
                  END
                END
2.Проверяем соединение с сервером.
3.Отдельным потоком висит скрытое окно с таймером или триггером, в котором выше указанная ThreadLogs в цикле начинает по NameBD и idRecBD находит запись и по idOper выполняет (add,change, delete) на удаленном сервере. Вопрос, правильна, живуча ли данная конструкция, может чего не хватает для живучести потока или еще чего :) Буду рад любым практичным советам , заранее спасибо. :)
И это всё должно не мешать параллельной работе в этой же программе пользователю. :cat:

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 8:20
Игорь Столяров
gopstop2007 писал(а): Пользователь (add,change, delete) запись в ЛЮБОЮ таблицу БД
Судя по описанию, у Вас принята какая-то своя внутренняя терминология и синтаксис ... Вообще это называется репликацией.
Тут все зависит от структуры данных, но в общем случае - такие действия должны выполняться под транзакцией, что бы в т.ч.
исключить доступ пользователя к промежуточным результатам репликации данных. А вообще лучше посмотреть по слову
"репликация" гугл или яндекс - на эту тему не одна книжка и диссертация написаны. ;)

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 10:19
kreator
А синхронизация в какую сторону? В одну? В обе? А отдельный поток зачем? Поподробнее опишите, что надо. Я недавно делал синхронизацию баз на планшете и в сети в обе стороны. Но у меня синхронизируется очень небольшая часть данных и, естественно, не универсально. Вообще репликация - очень неоднозначный механизм, и требующий больших затрат как программера так и архитектора БД.

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 11:10
gopstop2007
kreator писал(а):А синхронизация в какую сторону? В одну? В обе?
в данном случае в одну, от пользователя на удаленный сервер, справочники с товаром
kreator писал(а):А отдельный поток зачем?
Тут много причин, плохая связь (инет), невнимательность пользователя и так как товара порядка 25000 наименований решил автоматизировать. Пользователь добавляет, изменяет товар, при отправке может быть ошибка по причине отсутствия инета и отправку надо повторить и при том неоднократно :( Пользователь находится не в офисе, а вне черты городов и очень часто бывает в труднодоступных для связи местах. :(
Сам механизм отдельного потока рассматриваю как накопление порядка действий с товаром в отдельную таблицу ThreadLogs, после чего сам поток проверяет наличие соединения с сервером и выполняет отправку данных, при этом параллельно может выполнятся пополнение таблицы ThreadLogs при работе пользователя со справочником товара.
kreator писал(а): Я недавно делал синхронизацию баз на планшете и в сети в обе стороны.
Планшеты на андроиде или виндовс?

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 11:29
kreator
gopstop2007 писал(а):Планшеты на андроиде или виндовс?
На Винде.
Я понял. В общем-то всё логично, более-менее. Возможно, тред будет сильно тормозить работу, пока синхронизация не закончится, работать будет не комфортно. Я бы сделал отдельным exe-шником, можно повесить на расписание (планировщик заданий). Мы пользуем X-Starter, есть такая неплохая программа для задания расписания.
Единственное, я не понимаю (логически) - как сохранить целостность и актуальность этого справочника, если позволено станциям писать на удалённый сервер. Должна быть какая-то хитрая проверка на дубликаты и т.д.?

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 11:53
gopstop2007
kreator писал(а):Возможно, тред будет сильно тормозить работу, пока синхронизация не закончится, работать будет не комфортно. Я бы сделал отдельным exe-шником.
для начала попробую тредом, а потом через службу :)
kreator писал(а):Единственное, я не понимаю (логически) - как сохранить целостность и актуальность этого справочника, если позволено станциям писать на удалённый сервер.
В данном случае используется один (максимум два) пользователя которые работают со справочником товара, все изменения отправляются на сервер, остальные только "получают" изменения по справочнику.
Игорь Столяров писал(а):Вообще это называется репликацией.
В моем случае используются смешанный механизм синхронизации работы с сервером :) Я сильно упростил в сабже свой вопрос. ;)

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 14:00
Shur
А как решается вопрос с одновременной записью/удалением одной и той же записи справочника?

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 14:28
gopstop2007
Shur писал(а):А как решается вопрос с одновременной записью/удалением одной и той же записи справочника?
а в чём проблема, если в правильно понял, в моей схеме в данном случае используется метод синхронизации - репликации

Код: Выделить всё

1 шаг 
idOper = 2;  	! изменение
idRecBD =123	 ! индиф № записи 

2 шаг 
idOper = 3 	 ! удаление
idRecBD =123	! индиф № записи
как было указано выше, изменять справочник может только один определенный пользователь

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 15:13
Дед Пахом
У нас так (идея не моя): клиент шлёт на сервер не данные, а файлы базы данных (только изменённые записи), соответственно пофиг обрыв соединения - просто закачка заново. А на сервере крутится сервис, который периодически проверяет каталог закачки и сам добавляет в базу - тут уже никаких проблем с инетом нет и быть не может.

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 15:27
gopstop2007
Дед Пахом писал(а):У нас так (идея не моя): клиент шлёт на сервер не данные, а файлы базы данных (только изменённые записи), соответственно пофиг обрыв соединения - просто закачка заново. А на сервере крутится сервис, который периодически проверяет каталог закачки и сам добавляет в базу - тут уже никаких проблем с инетом нет и быть не может.
Согласен, я думал о таком варианте. В моем случае: TPS - на локальных машинах, MySQL - удаленный сервер с помощью которого решается дополнительно еще два аспекта, отправка накладных и заказов между филиалами.

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Декабрь 2015, 20:17
Shur
Извиняюсь, но вижу какую-то нестыковку:
gopstop2007 писал(а): В данном случае используется один (максимум два) пользователя которые работают со справочником товара
gopstop2007 писал(а): как было указано выше, изменять справочник может только один определенный пользователь
Так вот, предположим всё-таки, что пользователей больше одного. Как нужно поступать в данном случае? В этом случае вам просто необходимо в справочнике иметь поле TimeStamp (или назовите его Version). Реализовать его можно любым способом. Самое простое -- это завести его как int в базе (как LONG в tps), и инкрементировать его каждый раз, когда происходит изменение (INSERT/UPDATE) записи на сервере. Это поле нужно передавать на клиентские машины, а затем, после изменения записи на клиенте, после синхронизации лога при изменении на сервере сверять с текущим значением на сервере.
Условно говоря, примерно так:

Код: Выделить всё

update t set f1 = @f1, f2 = @f2, ..., TimeStamp = TimeStamp + 1
where ID = @IdRecBD 
and TimeStamp = @TimeStamp
Если значения не совпадают, то ни в коем случае обновлять запись нельзя, и для таких случаев нужно разработать механизм оповещения об ошибке обновления. Иначе один пользователь будет изменять у записи код ТН ВЭД, а другой пользователь всего лишь синтаксис в названии. И второй перезатрёт изменения, сделанные первым. В результате справочник в части ТН ВЭД будет не верным.

Отдельный Thread как отправка данных на сервер

Добавлено: 10 Декабрь 2015, 20:38
gopstop2007
Даже в указанном Вами варианте, проще сделать запись на сервер изменений в виде, см. рис. ниже
А у клиентов сохраняется номер по последнему изменению, а дальнейшее обновление по справочнику по списку с сервера

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Январь 2016, 13:01
gopstop2007
Столкнулся с проблемой при загрузке данных на сервер. Говоря другими словами, предположим что имеем два потока в программе, один выполняет условный цикл работы с данными (отправка на сервер), другой выполняет оконную процедуру ввода данных, и нам не важно когда закончится первый, а важно чтобы оконная процедура адекватно реагировала на запросы пользователя от мыши и клавы, т.е. больший приоритет был бы у оконной процедуры. Использование в первом процессе YIELD, и установка таймера в оконной процедуре большого выигрыша не дает, мышь дергается, реакция на клаву запоздалая, может кто и делал что подобное?

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Январь 2016, 14:30
kreator
Может поставить таймер в первом процессе? По типу формирования репорта. Окно, естественно, схайдить.

Отдельный Thread как отправка данных на сервер

Добавлено: 08 Январь 2016, 15:13
gopstop2007
kreator писал(а):Может поставить таймер в первом процессе? По типу формирования репорта. Окно, естественно, схайдить.
уже пробовал, результат тот же :(
В С10 появился класс с примером WorkingTreadDemo.app, сходу я его не осилил, кто то пробовал сие чудо, поможет ли он в моей ситуации?