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

Откуда:
Сообщений: 749
Есть вопрос, нужно временно заблокировать одну запись / поле чтобы можно было записать в нее значение и успеть его считать, так чтобы кто-то в сети за это промежуток времени, хоть и очень малый, не успел перебить это значение (вопрос уникальности ключей и интенсиивная работа одновремменых устройств.)
LOCK / RLOCK даже при успешной блокировке, разрешают почему-то делать Update..
1 фев 08, 18:41    [5234996]     Ответить | Цитировать Сообщить модератору
 Re: RLOCK / LOCK  [new]
Dima T
Member

Откуда:
Сообщений: 15279
update ждет освобождения записи. Проблема вероятно в том что чтение происходит до блокировки и update пишет что-то производное от прочитанного. Блокировка чтение не блокирует, только запись.
Например порядок такой:
1. Прочитать значение
2. заблокировать запись
3. изменить значение на +1
4. разблокировать

то при одновременном выполнении два разных пользователя выполнят одно и то же. Прочитают одновременно, а запишут по очереди. Т.е. вместо +2 окажется +1
1 фев 08, 18:53    [5235037]     Ответить | Цитировать Сообщить модератору
 Re: RLOCK / LOCK  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
Продолжая не законченную фразу, надо изменить последовательность действий:

1. Попытаться заблокировать запись
2. Если удалось заблокировать, читаем и изменяем значение
3. Снимаем блокировку.

Т.е. читать не ДО, а ПОСЛЕ успешной блокировки
1 фев 08, 19:03    [5235080]     Ответить | Цитировать Сообщить модератору
 Re: RLOCK / LOCK  [new]
И. В. К.
Member

Откуда:
Сообщений: 99
используйте буферизацию и requery()
получите сброс информации и одновременно считывание
1 фев 08, 19:52    [5235250]     Ответить | Цитировать Сообщить модератору
 Re: RLOCK / LOCK  [new]
И. В. К.
Member

Откуда:
Сообщений: 99
я бы поменял порядок

автор
1. Прочитать значение
2. заблокировать запись
3. изменить значение на +1
4. разблокировать


сделал бы так:

1.заблокировать запись
2.Прочитать значение
3. изменить значение на +1
4. разблокировать
1 фев 08, 19:55    [5235263]     Ответить | Цитировать Сообщить модератору
 Re: RLOCK / LOCK  [new]
И. В. К.
Member

Откуда:
Сообщений: 99
ВладимирМ
Продолжая не законченную фразу, надо изменить последовательность действий:

1. Попытаться заблокировать запись
2. Если удалось заблокировать, читаем и изменяем значение
3. Снимаем блокировку.

Т.е. читать не ДО, а ПОСЛЕ успешной блокировки


упс..
экскьюзми
уже поменяли..
1 фев 08, 19:57    [5235265]     Ответить | Цитировать Сообщить модератору
 Re: RLOCK / LOCK  [new]
И. В. К.
Member

Откуда:
Сообщений: 99
упс..
база фоксовая.. requ() не покатит..
1 фев 08, 20:06    [5235285]     Ответить | Цитировать Сообщить модератору
 Re: RLOCK / LOCK  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
В принципе, можно и без явных блокировок, но в этом случае придется ставить бесконечный цикл именно на случай изменения значений другим пользователем. Если написать код "в чистом виде", то это будет примерно так:

* Организуем бесконечный цикл
DO WHILE .T.
	* Отбираем нужную запись по ключу
	SELECT * FROM MyTab INTO CURSOR curValue NOFILTER WHERE Key = ...
	* Сохраняем текущее значение
	lnPrevValue = curValue.Value
	* Формируем новое значение
	lnNewValue = m.lnPrevValue + 1
	* Пытаемся записать
	UPDATE MyTab SET Value=m.lnNewValue WHER Key=... AND Value=m.lnPrevValue
	IF _TALLY = 1
		* Если удалось сделать запись прерываем цикл
		EXIT
	ENDIF
	* Запись сделать не удалось, повторяем все заново
ENDDO

Смысл в том, что в команде UPDATE-SQL модифицируется не просто запись с нужным значением ключа, но и с тем значением изменяемого поля, которое было прочитано изначально. До модификации.

Если такой записи нет (_TALLY=0), то это значит, что запись была изменена другим пользователем именно в промежуток между считыванием старого значения и его модификацией. В этом случае повторяем операцию.
1 фев 08, 22:52    [5235635]     Ответить | Цитировать Сообщить модератору
 Re: RLOCK / LOCK  [new]
Dima T
Member

Откуда:
Сообщений: 15279
ВладимирМ
В принципе, можно и без явных блокировок, но в этом случае придется ставить бесконечный цикл ...

Красивое решение, но я бы еще одну проверку добавил, чтобы не зациклилось случайно:
	...
	SELECT * FROM MyTab INTO CURSOR curValue NOFILTER WHERE Key = ...
	if _TALLY != 1
		MessageBox("Косяк")
		exit
	endif
	...
2 фев 08, 09:18    [5235981]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить