Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
vadca
0 / 0 / 0
Регистрация: 07.04.2016
Сообщений: 75
1

Запретить открывать форму с данными, если она уже открыта другими

08.12.2017, 12:41. Просмотров 377. Ответов 16
Метки нет (Все метки)

Добрый день. Есть список с данными, нажимая 2 раза, открывается форма с этими детальными данными. Там есть идентификационный код или серия. Нужно запретить, открытие формы по идентификационному коду если она уже открыта.

Возможно ?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.12.2017, 12:41
Ответы с готовыми решениями:

Визуализатор XML отображает уже стилизованную форму с данными
Копаюсь с данными из росреестра. Требуется парсить полученные от него xml файлы и далее печатать...

Запретить открытие формы если она уже открыта
Из главной формы открываю еще одну форму кнопкой. При повторном нажатии вызывается повторно...

Как определить, что открыта панель Персонализации и завершить её, если она открыта?
Я понимаю, что необходимо узнать Hendle окна. Но как узнать хэндл Панель управления\Все элементы...

Как запретить открывать форму?
ну скажем при определенных условиях? оптимально хотелось бы возможность скрыть ярлык в меню слева....

Как запретить работу в одной форме если открыта другая?
Подскажите, пожалуйста, как запретить работу в одной форме если открыта другая?

16
Grossmeister
Модератор
3535 / 2565 / 449
Регистрация: 21.01.2011
Сообщений: 11,189
08.12.2017, 12:50 2
Цитата Сообщение от vadca Посмотреть сообщение
Нужно запретить, открытие формы по идентификационному коду если она уже открыта.
Имеется ввиду запрет открытия на другом клиентском месте?
0
vadca
0 / 0 / 0
Регистрация: 07.04.2016
Сообщений: 75
08.12.2017, 13:13  [ТС] 3
Да, на другом ПК или на нескольких.

Добавлено через 20 минут
MS SQL Server база данных
0
Grossmeister
Модератор
3535 / 2565 / 449
Регистрация: 21.01.2011
Сообщений: 11,189
08.12.2017, 13:16 4
Цитата Сообщение от vadca
Да, на другом ПК или на нескольких
Полагаю, что зависит от СУБД.
Например, в Oracle есть конструкция SELECT ... FOR UPDATE. Если я при открытии формы делаю не просто SELECT, а SELECT FOR UPDATE, то СУБД проверяет, не заблокирована ли строка другим. Если заблокирована, то выдается ошибка, которую при обработке можно заменить на что-то вроде "Документ уже открыт другим пользователем".
0
08.12.2017, 13:16
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
08.12.2017, 13:20 5
Grossmeister, не, это вы уже жестите. Перед выдачей ошибки база знатно потупит (подождёт, пока снимется блокировка). Лучше завести отдельное поле в этой таблице (или в другой) с признаком блокировки записи. Хотя тут придётся следить за снятием этой записи, ибо клиент может отвалиться не почистив за собой запись.
0
Grossmeister
Модератор
3535 / 2565 / 449
Регистрация: 21.01.2011
Сообщений: 11,189
08.12.2017, 13:24 6
Цитата Сообщение от Usaga Посмотреть сообщение
Перед выдачей ошибки база знатно потупит (подождёт, пока снимется блокировка)
Нет. Точнее если просто SELECT FOR UPDATE, то да, программа перейдет в ожидание снятия блокировки.
А вот если SELECT FOR UPDATE NOWAIT, то будет попытка самому заблокировать строку, а если она уже заблокирована, то немедленно ORA-00054 resource busy
1
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
08.12.2017, 13:30 7
Grossmeister, но это если речь о обращении к базе в рамках транзакции. ТС просил удерживать блокировку на всё время открытия формы редактирования. А это значит, что придётся держать транзакцию пока не закроется форма редактирования. Мягко говоря, не очень правильное решение.

И не нужно ли прибавить HOLDLOCK, чтобы блокировка не уехала после выполнения запроса?
0
vadca
0 / 0 / 0
Регистрация: 07.04.2016
Сообщений: 75
08.12.2017, 13:39  [ТС] 8
Спасибо за идеи. Буду пробовать обе.
0
Grossmeister
Модератор
3535 / 2565 / 449
Регистрация: 21.01.2011
Сообщений: 11,189
08.12.2017, 13:50 9
Цитата Сообщение от Usaga
Мягко говоря, не очень правильное решение.
Во-первых, вряд ли кто-то станет специально долго держать открытую форму.
Во-вторых, открытая транзакция ничему не мешает.
В-третьих, если по бизнес-условиям во время редактирования инфы никто другой не имеет права редактировать эту же инфу, то другого способа, кроме как SELECT FOR UPDATE, обеспечить это нет.
А что касаемо самопальной реализации блокировок, то это обязательно будет приводить (хотя бы периодически) к тому, что эти блокировки будут оставаться. Тем более, что для того, чтобы изменение какого-то поля увидела другая сессия, это изменение надо зафиксировать с пом. COMMIT
0
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
08.12.2017, 13:55 10
Grossmeister, я согласен, что самопальная блокировка - дело такое, за ней следить нужно. Но можно решить и иначе: мьютексами на стороне сервера\клиента.

Удерживать монопольную блокировку над строкой\таблицей - плохое решение.

Добавлено через 54 секунды
Цитата Сообщение от Grossmeister Посмотреть сообщение
Во-первых, вряд ли кто-то станет специально долго держать открытую форму.
Открыть форму и пойти попить чая или поговорить по телефону с клиентом - чем не распространённая практика?
0
vadca
0 / 0 / 0
Регистрация: 07.04.2016
Сообщений: 75
08.12.2017, 14:04  [ТС] 11
Usaga, а как реализовать мьютексами на стороне сервера\клиента. ? Я мютекс реализовал на саму оболочку программы, чтобы не запускали несколько раз. А тут форма таже, но может содережать разные данные, исходя от серии, наврятли можно наложить мютекс
0
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
08.12.2017, 14:12 12
vadca, под "мьютексом" я имел в виду общий способ блокирования. Это не обязательно должен быть именно мьютекс или примитив синхронизации. Можно банально завести словарик (Dictionary) в который заталкивать серийный номер (или что у вас там идентифицирует запись) и какой-нибудь ID клиента взявшегося её редактировать.

Поскольку работа с данными идёт через один сервер, централизованно, то он всегда будет в курсе кто и что редактирует. PROFIT. Никаких "долгих" транзакций.
0
vadca
0 / 0 / 0
Регистрация: 07.04.2016
Сообщений: 75
08.12.2017, 14:24  [ТС] 13
А какой нибудь пример, может можно увидеть где нибудь? С этим еще не сталкивался. или по каким критериям гууглить
0
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
08.12.2017, 14:28 14
vadca, вам недостаточно совета про словарь?
0
hoolygan
356 / 283 / 76
Регистрация: 21.06.2016
Сообщений: 1,115
08.12.2017, 15:05 15
Как-то нелогично поставлена задача.
Если делать селект с удержанием, то, чисто теоретически, другой клиент даже реестр не увидит - так как должен получить хотя-бы айдишку с таблицы, где строка отбирается. И получит вечный дедлок в ожидании.
Переспросите заказчика, может быть нужно не давать права сохранять, пока открыта сессия на другой машине? Иначе задача довольно нетривиальная получается с множеством костылей в будущем.
0
vadca
0 / 0 / 0
Регистрация: 07.04.2016
Сообщений: 75
08.12.2017, 15:25  [ТС] 16
hoolygan, ок, как вариант, как запретить сохранять ?
0
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
08.12.2017, 16:05 17
vadca, вводите в таблицу поле типа timestamp и читаете её вместе со всеми данными, а в момент сохранения, добавляете её к в условию WHERE (update bla-blah where Id=@Id and Version=@Version). При изменении любого поля записи СУБД автоматически изменит и значение этого поля (оно сродни счётчику), потому последующие попытки обновить запись обломятся: версия-то изменилась и Update такую запись не найдёт.

Это очень популярный подход. Никаких блокировок. Только пользователя нужно будет известить, что сохранение не удалось так как целевая запись была изменена кем-то другим.
0
08.12.2017, 16:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.12.2017, 16:05

Не пересоздается директория QDir, если она открыта через файловый менеджер
Нужно удалить существующую директорию, если она есть и создать новую с тем же именем, т.е. очистить...

[WPF] Не открывать окно, если уже открыто
Интересует как можно автоматически сделать так, чтобы окно, если он уже открыто, не открывалось...

Ошибка, что база уже открыта oткрыть Exclusive уже неудaется.
Еслй етoт пример пoстaвить в цикл (типo пoвтoряетсья через 1 мин.), тo через кaкиx тo 25 - 35 рaзoв...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru