Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Проблема с сетевым InterBase  (Прочитано 9674 раз)
0 Пользователей и 1 Гость смотрят эту тему.
STP
Гость
« : 13-11-2005 16:07 » 

Подскажите, пожалуйста, как в сетевой версии программы избежать дублирования.
У меня в программе выставляются счета. Перед вводом счёта идёт запрос в базу для поиска предыдушего номера, после чего вводится новая позиция и делается commit.
При одновременной работе нескольких операторов появляются повторные номера. В чём может быть дело?
Записан
Oldy
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 14-11-2005 07:01 » 

Применяйте генераторы.
Записан

С уважением, Oldy.
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #2 : 14-11-2005 07:35 » 

STP, используй блокировки. Я в Интербейзе не силен, как конкретно сделать не подскажу, но теория говорит на этот счет вполне определенно. Рассмотрим пример, иллюстрирующий данную ошибку: пусть есть 2 пользователя, А и Б. Работают одновременно, и почти в одно и то же время захотели выставить счет. Что реально происходит (распишем по моментам времени):
1) Пользователь А прочитал последний номер счета из базы
2) Пользователь А формирует у себя на клиенте данные для сохранения в базу (например генерит новый номер счета). В это время пользователь Б читает из базы данных последний номер счета. О пользователе А он ничего не знает.
3) Пользователь А сформировал наконец счет и сохраняет его в базе данных. В этот момент пользователь Б формирует свой вариант нового счета. Понятно, что при условии идентичтоности алгоритмов генерации номеров счетов у всех пользователей пользователи А и Б сгенерят одинаковые идентификаторы счетов.
4) Пользователь Б сохраняет (а точнее пытается сохранить, СУБД не должна ему позволить это сделать) свой счет

Как с этим бороться: пользователь А после считывания последнего номера счета (в примере - шаг 1) ) должен поставить блокировку на таблицу. Если кто-то в это время обращается к таблице, то он ждет до освобождения блокировки (так происходит не всегда - читай документацию по Интребейзу). После вставки данных пользователь А разблокирует таблицу и пользователь Б может продолжить работу.\
Как поставить блокировку не знаю, в оракле есть такая вещь как SELECT .... FOR UPDATE. Попробуй копнуть Улыбаюсь

Кстати, как правильно сказал Oldy, можно не париться и применить генераторы, вот только я не уверен, что бизнес-логика позволяет сделать номер счета автоинкрементным. Если позволяет, то забудь про блокировки и введи в таблицу автоинкрементное поле (в SQL Server определяется как IDENTITY)
Записан
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #3 : 14-11-2005 07:39 » 

Вот кстати пара ссылок по теме:

Dark Flasher (10:36 AM) :
http://www.ibase.ru/devinfo/plocks.htm
Dark Flasher (10:36 AM) :
http://www.ibase.ru/devinfo/versions.htm
Dark Flasher (10:37 AM) :
http://www.ibase.ru/devinfo/pslock.htm
Записан
Oldy
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 14-11-2005 08:30 » 

Mouse wrote:
Цитата
А и Б. Работают одновременно, и почти в одно и то же время захотели выставить счет. Что реально происходит (распишем по моментам времени):
1) Пользователь А прочитал последний номер счета из базы
2) Пользователь А формирует у себя на клиенте данные для сохранения в базу (например генерит новый номер счета). В это время пользователь Б читает из базы данных последний номер счета. О пользователе А он ничего не знает.
3) Пользователь А сформировал наконец счет и сохраняет его в базе данных. В этот момент пользователь Б формирует свой вариант нового счета. Понятно, что при условии идентичтоности алгоритмов генерации номеров счетов у всех пользователей пользователи А и Б сгенерят одинаковые идентификаторы счетов.
4) Пользователь Б сохраняет (а точнее пытается сохранить, СУБД не должна ему позволить это сделать) свой счет

Если идти по пути предложенному Mouse т.е. применять блокировку, то предлагаю несколько изменить последовательность шагов:
1) Пользователь А формирует у себя на клиенте данные и добавляет их в базу (Insert)
2) Непосредственно перед вставкой сервером вызывается триггер Before Insert (при его наличии естественно) в котором формируется (вычисляется или генерируется) номер счета, здесь-то и нужно производить блокировку если не использовать генераторов.
3)Commit и снятие блокировки.

« Последнее редактирование: 14-11-2005 08:38 от Oldy » Записан

С уважением, Oldy.
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #5 : 14-11-2005 11:10 » 

Oldy, стопудово, так будет лучше. Табличка гораздо меньше времени будет под блокировкой простаивать. Вопрос только в том, должен ли пользователь знать, какой номер счета вводиться? По постановке задачи вроде получается что нет. Тогда вариант с триггерами - то что нужно Улыбаюсь Это если номера счетов какие-то хитрые. А если просто идентификатор, то делать поле IDENTITY и не заморачиваться долго Улыбаюсь
Записан
Oldy
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 14-11-2005 11:48 » 

"Сначала хотелось-бы послушать начальника транспортного цеха" -  (с) Жванецкий т.е. STP,  о типе номера счета. Улыбаюсь
« Последнее редактирование: 14-11-2005 12:09 от Oldy » Записан

С уважением, Oldy.
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #7 : 14-11-2005 12:27 » 

Чтож, будем ждать начальство  Отлично
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines