Как обеспечить "единственность" обработки записи?

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Aleksandr.
Сообщения: 63
Зарегистрирован: 18 май 2005, 19:13

Как обеспечить "единственность" обработки записи?

Сообщение Aleksandr. » 17 авг 2006, 16:04

FB 1.5.3.
С одной базой работают две программы - серверная, обеспечивающая общее управление базой и подключаемыми клиентами, и n экземпляров клиенской, предназначенной для просмотра/редактирования записей. Для серверной предполагается возможность отключения режима интерактивности, и все MessageBox и т.д., которые могут на ней вызываться, должны быть показаны только на первом поймавшем Event клиенте. Я попытался сделать так:
создал таблицу AppMessages(ID INT NOT NULL, MsgCaption VARCHAR(50), MsgText VARCHAR(250), MsgButtons INT, MsgResult INT), серверная программы записывает в эту таблицу сообщение, проставляя MsgResult в -1, затем вызывает нужный POST_EVENT, зарегестрированный на клиентах. Расчет делается на то, что первый поймавший Event клиент отредактирует запись, установив MsgResult в -2 в качестве блокировки, дабы остальные, увидев -2, не трогали его, а потом покажет окно диалога, и по его завершении пропишет в MsgResult нажатую кнопку, вызвав затем Event для сервера, чтобы тот считал результат.
Проблема в том, что я плохо представляю себе механизм блокировки записей и событий, и мне представляется, что остальные клиенты могут также успеть прочесть запись до того момента, как она будет заблокирована через поле MsgResult.
Как можно обеспечить эту схему, чтобы гарантированно не дать работать с записью после получения Event более чем одному клиенту?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 авг 2006, 16:11

Как можно обеспечить эту схему, чтобы гарантированно не дать работать с записью после получения Event более чем одному клиенту?
не вижу проблем, что все читают. а вот обновлять конкретную запись может только один. как только он сделает update этой записи, все остальные клиенты пытаясь сделать update получат ошибку. Если, конечно, тот "первый" клиент не сделает commit после этого update.

Aleksandr.
Сообщения: 63
Зарегистрирован: 18 май 2005, 19:13

Сообщение Aleksandr. » 17 авг 2006, 16:19

То есть, для блокировки конкретной записи в данной ситуации мне надо выполнить запрос на UPDATE без COMMIT, и воткнуть его в блок обработки ошибки, который в случае исключения должен пропустить показ сообщения?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 авг 2006, 17:16

примерно так.
я плохо представляю себе механизм блокировки записей
все оч. просто - одну запись единовременно может "редактировать" только один "клиент".
www.ibase.ru/devinfo/mga.htm

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 17 авг 2006, 17:20

Select Чаво нада From AppMessages Where ID=:ID With Lock

Aleksandr.
Сообщения: 63
Зарегистрирован: 18 май 2005, 19:13

Сообщение Aleksandr. » 17 авг 2006, 17:28

Merlin писал(а):Select Чаво нада From AppMessages Where ID=:ID With Lock
А select остальных вызовет ошибку?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 авг 2006, 19:52

А select остальных вызовет ошибку?
ты всегда только спрашиваешь, и ничего не читаешь?
www.ibase.ru/devinfo/pslock.htm

Ответить