Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Update conflict / 7 сообщений из 7, страница 1 из 1
29.09.2009, 10:25
    #36221962
For Peace
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Update conflict
В многопользовательской программе, разные люди вносят в одну и ту же строку, но в разные поля, свои данные, буферизация таблицы 5, и после завершения программы у многих пользователей когда вылетает ошибка Update conflict. Это вроде и нормальная реакция, но все построено так, чтобы вроде миновать эту ошибку. Например к таблице прямое обращение возникает только тогда когда пользователь нажимает кнопку записи, и после того как эти миллисекунды времени обращенные к таблице во время записи, и команды tableupdate(.t.), и принудительного снятия блокировки rlock(.f.) все равно вылетает иногда эта ошибка.
И кажись дело даже не в одновременном доступе к записи. А в том что отредактированная запись другим человеком и успешно сохраненная им же изменения, не обновляются для другого пользователя. Как например другой пользователь перед записю может запросить самые последние данные на текущую секунду, а не старые буферизированные данные? Если есть такая функция, назовите мне ее пожалуйста.
...
Рейтинг: 0 / 0
29.09.2009, 10:31
    #36221975
Ffffffffffffffff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Update conflict
Лучше бы вы код привели, чем столько мыслей неупорядоченных.
...
Рейтинг: 0 / 0
29.09.2009, 10:45
    #36221994
For Peace
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Update conflict
Код простой, каждый работает с локальным view. И когда им приспичит они сохраняют в таблицу свои изменения. Как запросить последнее состояние строчки, куда сохраняют все пользователи, но не одновременно?
...
Рейтинг: 0 / 0
29.09.2009, 11:10
    #36222066
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Update conflict
Local View - это ДРУГАЯ таблица. Это не есть таблица источник. Следовательно, чтобы перенести изменения из этой таблицы в исходную таблицу надо выполнить некие операции. Это делается при помощи команд Select-SQL. Например, обновление при помощи команды UPDATE-SQL.

Естесственно, что необходимо указать что именно, какую запись, следует изменить. Т.е. написать условие WHERE к этой команде.

Если в команде TableUpdate() не указывать второй параметр, то условие WHERE будет сформировано примерно так:

Код: plaintext
WHERE keyField = oldValue0 and updateField1 = oldValue1 and updateField2 = oldValue2 and ...

Т.е. поиск записи будет осуществляться не только по ключевому полю, но и по значению всех модифицируемых полей. По их значению, которое было на момент начала модификации (то, что возвращает функция OldVal()) Каких именно полей, зависит от переключателя "SQL WHERE clauses include" на закладке "Update Criteria" в дизайнере View.

Если запись была изменена другим пользователем или же этим же самым пользователем, но в другом DataSession, то, естесственно, запись найдена не будет. Ведь OldVal() окажется отличным от того, что сейчас реально записано в поле таблицы. Это и пораждает сообщение Update Conflict исходя из предположения, что запись не найдена по той причине, что изменены поля для модификации.

Если использовать второй параметр в функции TableUpdate() в значении .T., т.е. писать

Код: plaintext
=TableUpdate(.T.,.T.)

то условие WHERE будет сформировано примерно так

Код: plaintext
WHERE keyField = oldValue0

Вне зависимости от значения переключателя "SQL WHERE clauses include". Т.е. останется только поиск по значению ключевого поля.

Поскольку, как правило, значение ключевого поля никогда не меняется, то вероятность "потерять" запись и получить сообщение "Update Conflict" прапктически отсутствует.

Что именно использовать - зависит от конкретной задачи. Ведь во втором случае вы просто перезапишете данные введенные другим пользователем.
...
Рейтинг: 0 / 0
29.09.2009, 12:48
    #36222399
For Peace
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Update conflict
Все написанное справедливо и вроде понятно, в моем случае я обновляю данные не sql-update-ом а просто нахожу дату в таблице, которая уникальна в самой базе и является своего рода ключевым. А далее replace-ом выполняю замену значений... Не знаю что предпочтительнее в данном случае, не знаю существенна ли разница между двумя этими методами, если да переписать в пользу sql-update, тоже не составит труда.
Но остается одно непонимание, если нет обращений к строкам базы и нет даже перемещений в нем, как например с разницой в несколько минут, два человека записывая в одну и туже запись (с одной датой, но в разные поля), может созревать эта ошибка... стало быть второй человек который пытается внести поверх свои данные, даже по истечении какого то времени имеет дело со старыми данными, минутной давности - раз генерится ошибка. Чем обусловлена такая задержка между пользователями и сервером в таком случае? И поможет ли мне команда requery() - первый раз о ней видел здесь на форуме, эта команда только для view или сетевым ресурсам тоже?
...
Рейтинг: 0 / 0
29.09.2009, 13:17
    #36222494
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Update conflict
For Peace
Но остается одно непонимание, если нет обращений к строкам базы и нет даже перемещений в нем, как например с разницой в несколько минут, два человека записывая в одну и туже запись (с одной датой, но в разные поля), может созревать эта ошибка...
Данные запоминаются на клиенте в момент открытия View или после выполнения Requery()

В момент сохранения происходит проверка что данные на сервере не изменились. Если изменились, то происходит ошибка "Update conflict"
Способ проверки изменений зависит от свойства WhereType :
VFP helpWHERE - предложение для модификаций отдаленных таблиц. WhereType может принимать следующие значения:

1 или DB_KEY (из FOXPRO.H). Предложение WHERE используется, чтобы обновить отдаленные таблицы, состоящие только из первичных полей, указанных в свойстве KeyFieldList.

2 или DB_KEYANDUPDATABLE (из FOXPRO.H). Предложение WHERE используется, чтобы обновить отдаленные таблицы, состоящие из первичных полей, указанных в свойстве KeyFieldList и любые обновляемые поля.

3 или DB_KEYANDMODIFIED (из FOXPRO.H). Предложение WHERE используется, чтобы обновить отдаленные таблицы, состоящие из первичных полей, указанных в свойстве KeyFieldList и любые другие поля, которые модифицируются. (Значение по умолчанию)

4 или DB_KEYANDTIMESTAMP (из FOXPRO.H). WHERE - предложение, используемое, чтобы обновить отдаленные таблицы, состоящие из первичных полей, указанных в свойстве KeyFieldList и сравнить временнЫе метки.
Если тебе не принципиально были изменения или нет, то используй DB_KEY
Это либо в визарде создания View поставить, либо выполнить:
Код: plaintext
DbSetProp('MyView', 'View', 'WhereType',  1 )
...
Рейтинг: 0 / 0
29.09.2009, 13:52
    #36222620
Kruchinin Pahan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Update conflict
For PeaceВсе написанное справедливо и вроде понятно, в моем случае я обновляю данные не sql-update-ом а просто нахожу дату в таблице, которая уникальна в самой базе и является своего рода ключевым. А далее replace-ом выполняю замену значений... Не знаю что предпочтительнее в данном случае, не знаю существенна ли разница между двумя этими методами, если да переписать в пользу sql-update, тоже не составит труда.
Но остается одно непонимание, если нет обращений к строкам базы и нет даже перемещений в нем, как например с разницой в несколько минут, два человека записывая в одну и туже запись (с одной датой, но в разные поля), может созревать эта ошибка... стало быть второй человек который пытается внести поверх свои данные, даже по истечении какого то времени имеет дело со старыми данными, минутной давности - раз генерится ошибка. Чем обусловлена такая задержка между пользователями и сервером в таком случае? И поможет ли мне команда requery() - первый раз о ней видел здесь на форуме, эта команда только для view или сетевым ресурсам тоже?
Иээхх... Почему-то вы выборочно прочитали сообщение от Владимира.

Вы делаете REPLACE по логическому представлению (LOCAL VIEW). А LOCAL VIEW не имеет прямой связи с таблицей(ами)-источником(ами). Взаимосвязь осуществляется только посредством команд-SQL.

Поэтому, в ответ на ваш REPLACE представление, в свою очередь, создает SQL-команду к первоначальной таблице. Эта SQL-команда выглядит как "UPDATE ... SET ... WHERE ..."

Проблема возникает именно из-за условия WHERE. Как настроить это условие, Владимир вам показал.
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Update conflict / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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