Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / FoxPro, Visual FoxPro Новый топик    Ответить
 Многопользовательский режим, запись в dbf-таблицу  [new]
SolnceJasnoe
Member

Откуда:
Сообщений: 8
Большая просьба помочь советом, что смотреть. Есть маленькая программка для одного пользователя по регистрации исходящей почты. Есть dbf-таблица с одним полем num, откуда берется порядковый номер исходящего отправления (счетчик наращивается на 1 каждый раз при записи очередного отправления), и сама база (тоже отдельная dbf-таблица) исходящих отправлений. Возникла необходимость работы вдвоем. Пробуем вводить с двух компьютеров - данные, введенные одним пользователем, затирают введенные другим. Запись в таблицу идет через INSERT. На время записи блокируем при помощи FLOCK сначала таблицу со счетчиком, затем саму таблицу регистрации. FLUSH FORCE сразу после записи не помогло. Опыта создания многопользовательских приложений нет, только маленькие программы обработки в VFP 6.0.
12 окт 21, 22:35    [22382877]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
Dima T
Member

Откуда:
Сообщений: 16063
INSERT не может потерять данные, что-то ты не договариваешь. Для вставки вообще не надо блокировки.

В твоем случае достаточно сделать гарантированно уникальный номер. Для этого достаточно блокировки записи с номером, как понимаю она у тебя одна.

Получение номера так:
func GetNum
local lnNum
if rlock('nomer') && Блокировка записи
   lnNum = nomer.num + 1
   repl in nomer num with lnNum
   unlock in nomer
else
  lnNum = -1
endif
return lnNum


Вставка
lnNum = GetNum()
...
if lnNum > 0
   insert into ...
endif

А лучше на 9-й фокс перейти, там есть поля с автоинкрементом, которые решают проблему со счетчиком.
13 окт 21, 07:36    [22382934]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
SolnceJasnoe
Member

Откуда:
Сообщений: 8
Dima T,
кнопка записи сейчас так (num - счетчик, jurnal - таблица регистрации почты), prizn=1 - режим ввода, иначе - режим редактирования

SET REPROCESS TO 5
IF m.prizn=1

SELECT num
IF FLOCK()
LOCATE FOR god=STR(god_jur,4)
IF !EOF()
m.num=num.num
REPLACE num WITH num+1
FLUSH FORCE
ELSE
m.num=1
INSERT INTO num (god,num) VALUES (STR(m.god_jur,4),m.num)
ENDIF
ENDIF
FLUSH force
UNLOCK


SElECT adresat
IF FLOCK()
IF !SEEK(m.adresat)
m.kod_t=0
ENDIF
ENDIF
UNLOCK
SELECT jurnal
IF FLOCK()
INSERT INTO jurnal(god,datareg,num,dsp,kod_nt,adresant,tema,kod_t,adresat,kod_vid,vid,kod_konv,vid_konv,rospis,operator,data_vv,time_vv) ;
VALUES (STR(YEAR(datareg),4),m.datareg,m.num,m.dsp,m.kod_nt,m.adresant,m.tema,m.kod_t,m.adresat,m.kod_vid,m.vid,m.kod_konv,m.vid_konv,m.rospis,m.fio_vib,DATE(),TIME())
ENDIF
FLUSH force
UNLOCK

ELSE

SElECT adresat
IF FLOCK()
IF !SEEK(m.adresat)
m.kod_t=0
ENDIF
ENDIF
UNLOCK

SELECT jurnal
IF FLOCK()
REPL kod_nt WITH m.kod_nt,adresant WITH m.adresant, tema WITH m.tema, kod_t WITH m.kod_t, adresat WITH m.adresat, kod_vid WITH m.kod_vid,;
vid WITh m.vid, kod_konv WITH m.kod_konv, vid_konv WITH m.vid_konv, rospis WITH m.rospis, dsp WITH m.dsp, operator WITH m.fio_vib,data_vv WITH DATE(),;
time_vv WITH TIME()
ENDIF
FLUSH force
UNLOCK


ENDIF
SELECT jurnal



RELEASE ThisForm


Пусть бы счетчик сбивался, записи были с одинаковым номером, мне не непонятно, почему один пользователь вводит - видит свои записи на Gridе, второй видит свои (кнопка записи расположена на форме с Grid). Но по выходу в базе записи только одного пользователя, будто второй ничего не записывал.
13 окт 21, 20:36    [22383345]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
Dima T
Member

Откуда:
Сообщений: 16063
SolnceJasnoe
Dima T,
кнопка записи сейчас так (num - счетчик, jurnal - таблица регистрации почты), prizn=1 - режим ввода, иначе - режим редактирования
+

SET REPROCESS TO 5
IF m.prizn=1

	SELECT num
	IF FLOCK()
		LOCATE FOR god=STR(god_jur,4)
		IF !EOF()
			m.num=num.num
			REPLACE num WITH num+1
			FLUSH FORCE
		ELSE
			m.num=1
			INSERT INTO num (god,num) VALUES (STR(m.god_jur,4),m.num)
		ENDIF
	ENDIF
	FLUSH force
	UNLOCK


	SElECT adresat
	IF FLOCK()
		IF !SEEK(m.adresat)
			m.kod_t=0
		ENDIF
	ENDIF
	UNLOCK
	SELECT jurnal
	IF FLOCK()
		INSERT INTO jurnal(god,datareg,num,dsp,kod_nt,adresant,tema,kod_t,adresat,kod_vid,vid,kod_konv,vid_konv,rospis,operator,data_vv,time_vv) ;
			VALUES (STR(YEAR(datareg),4),m.datareg,m.num,m.dsp,m.kod_nt,m.adresant,m.tema,m.kod_t,m.adresat,m.kod_vid,m.vid,m.kod_konv,m.vid_konv,m.rospis,m.fio_vib,DATE(),TIME())
	ENDIF
	FLUSH force
	UNLOCK

ELSE

	SElECT adresat
	IF FLOCK()
		IF !SEEK(m.adresat)
			m.kod_t=0
		ENDIF
	ENDIF
	UNLOCK

	SELECT jurnal
	IF FLOCK()
		REPL kod_nt WITH m.kod_nt,adresant WITH m.adresant, tema WITH m.tema, kod_t WITH m.kod_t, adresat WITH m.adresat, kod_vid WITH m.kod_vid,;
			vid WITh m.vid, kod_konv WITH m.kod_konv, vid_konv WITH m.vid_konv, rospis WITH m.rospis, dsp WITH m.dsp, operator WITH m.fio_vib,data_vv WITH DATE(),;
			time_vv WITH TIME()
	ENDIF
	FLUSH force
	UNLOCK


ENDIF
SELECT jurnal 



RELEASE ThisForm

Пусть бы счетчик сбивался, записи были с одинаковым номером, мне не непонятно, почему один пользователь вводит - видит свои записи на Gridе, второй видит свои (кнопка записи расположена на форме с Grid). Но по выходу в базе записи только одного пользователя, будто второй ничего не записывал.

Ты хочешь чтобы мы тут глаза сломали об твой код? Для оформления кода есть тэг SRC и отступы надо делать. Большие куски кода под спойлер надо прятать. Поправил.

Код ужасный, но в целом ничего криминального не вижу, должно работать. Единственное что может быть: у второй проги m.prizn!=1, она как-то оказывается на той записи jurnal, которую записала первая и пишет поверх нее.

Точно пропадают записи? Может не показываются? Попробуй запустить 2 копии проги, в каждой добавь по одной записи, закрой обе, заново открой одну и посмотри что получилось.
После каждого шага можешь запускать фокс и смотреть что в таблице jurnal.

FLUSH тут лишний.
14 окт 21, 08:15    [22383441]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7919
Дима уже спросил, я уточню его вопрос. У тебя код выглядит так

if m.prizn=1
    SELECT jurnal
    insert into (...)
else
    SELECT jurnal
    replace (...)
endif


Другими словами, сам код допускает изменение ранее введенной записи. Вопрос в том, на какой именно записи в этот момент находится указатель записи? Имею в виду, на команде Replace. По твоему коду - на текущей. Но это какая? Случайно не та, что только что создал другой пользователь?

Можешь здесь ДО команды Replace посмотреть какая именно запись текущая? Т.е. вывести куда-то реквизиты той записи, которую обновляешь? Ну, или в отладчике посмотреть.
18 окт 21, 14:55    [22385051]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
SolnceJasnoe
Member

Откуда:
Сообщений: 8
ВладимирМ, оба пользователя работают на ввод (m.prizn=1) - проверяю пока только эту ветку, т.е. команда INSERT. Есть форма c Grid с уже введенными записями, на ней кнопка, открывающая форму ввода новой записи, на ней кнопка сохранения. В кнопке сохранения указанный код - записи должен присвотся очередной номер при сохранении. Запускаю программу из сетевой папки на двух компьютерах до формы Grid и начинаю ввод. Ввожу и сохраняю запись на компьютере №1, отображается в Grid. На компьютере №2 программа уже запущена, открыта форма с Grid. но введенная на компьютере №1 запись в Grid на компьютере №2 не отображается. Ввожу на компьютере №2 запись - она сохраняется с тем же номером , что и предыдущая , введенная на компьютере №1, т.е. на двух компьютерах в Grid под одним и тем же номером разные записи. При выходе из программы в dbf под присвоенным номером сохраняется последняя введенная запись , т.е. с компьютера №2. Открываю таблицу нумерации и в процессе ввода смотрю изменение в ней номера - при вводе первой записи на компьютере №1 номер увеличивается на 1, при вводе с компьютера №2 следующей записи номер не изменяется. Времени и сил разбираться с буфферизацией нет, хотелось обойтись минимальными изменениями - SET EXCLUSIVE OFF , но не получается. Была написана изначально маленькая программка для одного человека , четыре года работала, теперь начальство хочет, чтобы работали одновременно два человека.
19 окт 21, 23:26    [22385654]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7919
Так не бывает. Не может INSERT работать как UPDATE (REPLACE). А Вы уверены, что оба пользователя работают с одной и той же DBF таблицей?

Т.е. начать надо с уточнения того факта, что оба пользователя работают с одной и той же таблицей DBF. Возможно, есть копии таблиц в других папках. Физически, это будет выражаться в том, что в ту таблицу DBF на которую Вы смотрите, записи будет добавлять только один из пользователей. Никакие данные другого пользователя вообще не сохраняться в эту таблицу

Кстати, а после повторного открытия приложения оба пользователя видят ранее внесенные данные? Это тоже проверка того факта, что работают с одной или с разными таблицами.
20 окт 21, 10:27    [22385733]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
SolnceJasnoe
Member

Откуда:
Сообщений: 8
ВладимирМ,
ситуация выглядит так, будто после входа в программу у каждого пользователя своя копия базы , поэтому и нумерация у обоих идет параллельно. И в dbf после выхода из программы в результате сбрасывается копия того пользователя, который последний ввел и сохранил данные. Что-то не так прописано на этапе открытия таблиц (таблицы открываются в главной форме в Data Environment), что нужно, чтобы записи напрямую попадали в таблицу? Запускаю программу на одном и на втором компьютере, ввожу на первом три записи под номером 51,52,53. Отображаются в Grid на текущем компьютере, на втором в Grid этих записей нет. На втором компьютере ввожу запись - попадает в Grid под номером 51. Выхожу из программы на обоих компьютерах, в базе последняя запись под номером 51, введенная на втором компьютере. Т.е. физически записи сразу в dbf не пишутся.
21 окт 21, 23:01    [22386707]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
Dima T
Member

Откуда:
Сообщений: 16063
В Data Environment отключи всем таблицам буферизацию. Правая кнопка - Properties - BufferModeOverride = None
22 окт 21, 07:37    [22386742]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
Dima T
Member

Откуда:
Сообщений: 16063
SolnceJasnoe
Выхожу из программы на обоих компьютерах, в базе последняя запись под номером 51, введенная на втором компьютере. Т.е. физически записи сразу в dbf не пишутся.

После входа 51 у обоих видно ?
22 окт 21, 07:39    [22386743]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
SolnceJasnoe
Member

Откуда:
Сообщений: 8
Dima T, перед обращением сюда прочитано все, что нашлось в поиске по похожей проблеме. Буфферизацию отключена. Да, при входе с любого компьютера вижу один и тот же результат - записывается физически данные с компьютера, где сохранялись последние данные.
24 окт 21, 18:11    [22387402]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
x1ca4064
Member

Откуда:
Сообщений: 1356
SolnceJasnoe
Буфферизацию отключена.

А у Вас сеть не на SMB2 работает, случайно?
Если случайно - попробуйте отключить SMB2, запретив mrxsmb20
24 окт 21, 19:29    [22387420]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
Dima T
Member

Откуда:
Сообщений: 16063
SolnceJasnoe
Dima T, перед обращением сюда прочитано все, что нашлось в поиске по похожей проблеме. Буфферизацию отключена. Да, при входе с любого компьютера вижу один и тот же результат - записывается физически данные с компьютера, где сохранялись последние данные.

Тогда не может быть того о чем ты пишешь. Есть что-то еще, что ты не замечаешь.

insert вставляет записи с разных машин, даже без блокировок ничего не потеряется. Без блокировок другие проблемы могут возникать, но не то что ты пишешь.

Т.к. по твоему мнению все что можно перепробовано, и ты ожидаешь от нас совет сделать еще какое-то мистическое действие чтоб заработало - разочарую, все что можно уже перебрали.

Остается последний вариант: сделай простейший проект, показывающий проблему: 1 таблица, 1 форма. На форме грид, текстбокс и кнопка "Вставить". По кнопке выполняется insert текста, который в текстбоксе.

Затем проверяешь что исчезновение записей происходит и выкладываешь этот проект сюда.
25 окт 21, 09:51    [22387549]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
x1ca4064
Member

Откуда:
Сообщений: 1356
SolnceJasnoe,
По поводу SMB:
вот маленький тест (размер чуть великоват для sql.ru, поэтоту ссылка) SmbDet
25 окт 21, 16:01    [22387827]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
x1ca4064
Member

Откуда:
Сообщений: 1356
SolnceJasnoe
Да, при входе с любого компьютера вижу один и тот же результат - записывается физически данные с компьютера, где сохранялись последние данные.


Если 2 экземляра запустить на одном ПК из локального каталога, беда есть?
26 окт 21, 13:13    [22388312]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
SolnceJasnoe
Member

Откуда:
Сообщений: 8
x1ca4064,
если на одном компьютере запустить дважды программу на сервере и вврдить поочередно данные - все в порядке, все записи на месте. Единственное, если вводишь данные в сессии №1, в Grid сессии №2 данные , только что введенные в сессии №1, не отображаются. Но после сохранения записи в сессии №2, в Grid сессии №2 появляются и перед этим сохраненные записи сессии №1, и введенная только что запись.
27 окт 21, 21:15    [22389112]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
x1ca4064
Member

Откуда:
Сообщений: 1356
SolnceJasnoe
x1ca4064,
если на одном компьютере запустить дважды программу на сервере и вврдить поочередно данные - все в порядке, все записи на месте.

Т.е. проблема возникает, когда работают по сети?
Если это так, то повторно рекомендую попробовать отключить SMB2 и проверить.
28 окт 21, 05:16    [22389183]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
Dima T
Member

Откуда:
Сообщений: 16063
SolnceJasnoe
Единственное, если вводишь данные в сессии №1, в Grid сессии №2 данные , только что введенные в сессии №1, не отображаются.

Это нормально, грид сам не перечитывает данные из таблицы. Надо сделать Grid.Refresh(), тогда появятся.

Судя по написанному проблема действительно с сетью. Что за сеть, какая ОС на сервере?
28 окт 21, 07:13    [22389187]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
SolnceJasnoe
Member

Откуда:
Сообщений: 8
x1ca4064, запускаю по сети (в сетевой папке) с одного компьютера дважды программу - все нормально, с разных компьютеров в этой же сетевой папке - данные одного затирают данные другого.
28 окт 21, 22:27    [22389640]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
x1ca4064
Member

Откуда:
Сообщений: 1356
SolnceJasnoe
x1ca4064, запускаю по сети (в сетевой папке) с одного компьютера дважды программу - все нормально, с разных компьютеров в этой же сетевой папке - данные одного затирают данные другого.

Могу в третий раз посоветовать отключить SMB2 :)
28 окт 21, 22:32    [22389642]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
SolnceJasnoe
Member

Откуда:
Сообщений: 8
Dima T,
Refresh есть в Activate формы, и для своего Grid отрабатывает, а вот данные, введенные на одном компьютере , на другом не отображаются. Выглядит все так, что у каждого пользователя своя виртуальная копия таблицы, в которую пишутся свои данные и по закрытию программы на обоих компьютерах физически в таблице на сервере сохраняются копия с того компьютера, в которй были последние по времени изменения. По поводу сети и сервера сейчас ответить не могу.
28 окт 21, 22:39    [22389644]     Ответить | Цитировать Сообщить модератору
 Re: Многопользовательский режим, запись в dbf-таблицу  [new]
Dima T
Member

Откуда:
Сообщений: 16063
SolnceJasnoe
Dima T,
Refresh есть в Activate формы, и для своего Grid отрабатывает, а вот данные, введенные на одном компьютере , на другом не отображаются. Выглядит все так, что у каждого пользователя своя виртуальная копия таблицы, в которую пишутся свои данные и по закрытию программы на обоих компьютерах физически в таблице на сервере сохраняются копия с того компьютера, в которй были последние по времени изменения. По поводу сети и сервера сейчас ответить не могу.

Ты уже сам подтвердил что проблема в сети, с ней и разбирайся. Фокс ни при чем, доказано на 100%. Почитай что x1ca4064 писал.
29 окт 21, 07:31    [22389714]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить