Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Запрет пользователям работать с одной и той же строкой

Автор вопроса: K RichardОтветов: 6

У меня на работе есть веб-приложение, похожее на систему работы с билетами. Некоторые пользователи вводят новые вопросы. Другие работники выбирают и решают вопросы. Все данные хранятся в MS SQL Server 2005.

Пользователи, работающие над решением проблем, переходят на страницу, где они могут просматривать открытые проблемы. Поскольку до двадцати человек могут просматривать эту страницу одновременно, одной потенциальной проблемой, которую мне нужно было решить, было то, что произойдет, если кто-то выберет проблему, которую кто-то другой выбрал сразу после загрузки их страницы.

Чтобы решить эту проблему, я сделал две вещи. Во-первых, gridview, отображающий проблемы для выбора, использует таймер AJAX для обновления каждую секунду. Как только проблема выбрана, она исчезает максимум через одну секунду. Если они выбирают один в течение этой секунды, они получают сообщение с просьбой выбрать другой.

Проблема в том, что часть AJAX отправляет слишком много обновлений (это то, что я предполагаю), и это влияет на производительность страницы и базы данных. Кроме того, обновления не выполняются каждую секунду. Я считаю, что таймер ненадежен при запуске хранимых процедур.

Должен быть лучший способ, но я не могу его найти. Есть ли у кого-нибудь опыт работы с подобной ситуацией или есть предложения, чтобы несколько пользователей не выбирали одну и ту же запись для сохранения? Я действительно не хочу полностью отключать часть AJAX, потому что я чувствую, что само по себе сообщение затруднит использование приложения.

Спасибо,

ajaxsql-serverconcurrency

Ответы

Ответ 1 · рейтинг 3 · Jacob Proffitt

Две вещи могут помочь смягчить вашу проблему.

Во-первых, уведомление после выбора о том, что дело было принято, необходимо независимо от ваших временных рамок обновления ajax. Даже проверка каждую секунду не означает, что два человека не могут щелкнуть одно и то же дело в одно и то же время. В таких случаях один из пользователей должен быть уведомлен о том, что его выбор недействителен, даже если он казался действительным при выборе. Это уведомление не должно быть сложным; поддержание легкого, полезного тона может улучшить восприятие пользователя даже в свете разочарования. И если вы идентифицируете пользователя, который уже выбрал эту запись, это не только поможет вашим пользователям координировать свои действия в будущем, но и отвлечет внимание от вашей программы на пользователя, который скрыл пикантный случай. (действительно, руководству может понравиться предоставление вашим пользователям случайных коллизий, поскольку это будет мотивировать их быстрее выбирать дела)

Во-вторых, небольшая настройка того, как вы отображаете свои дела, может уменьшить коллизии выбора. Добавление случайного элемента для порядка отображения и/или фильтрация каждого другого отображаемого случая поможет вашим пользователям естественным образом выбирать разные случаи. Распознавание человеческих образов и выбор задач на самом деле не случайны, поэтому небольшие изменения в представлении могут равняться большим изменениям в поведении выбора. Уменьшение вероятности столкновения делает ваши уведомления о столкновениях редкими (и, следовательно, менее раздражающими для ваших пользователей). Это еще лучше, если ваших пользователей можно разделить на классификации, которые могут помочь определить полезный порядок/фильтрацию случаев.

Хорошо, третья вещь, которая поможет вам со временем, - это если вы будете вести журнал, когда происходят столкновения (с полезными метаданными о столкновении, например, кто был вовлечен и время выбора). Вооружившись достоверными данными о столкновениях, вы сможете определить, что работает, а что нет. Со временем вы сможете отточить свое приложение до реальных вариантов использования, а также заранее выявить потенциальные проблемы. Ничто так не успокаивает пользователей, как понимание проблемы (и возможность объяснить свои планы по ее решению) еще до того, как они узнают о ее существовании.

С помощью этих смягчающих шаблонов вы, вероятно, обнаружите, что можете безопасно сократить время запроса ajax, не влияя на работу пользователей. А с полезным ведением журнала вы будете уверены, что любые настройки, которые вы вносите, действительно работают (или нет, что, возможно, еще полезнее знать).

Ответ 2 · рейтинг 4 · craigmoliver

Поместите поле метки времени блокировки в строку в базе данных. Напишите хранимую процедуру, которая возвращает true или false, если срок действия timsetamp старше определенного времени. Установите срок действия ваших сеансов в веб-приложении в одно и то же время, через минуту или две. Когда пользователь выбирает строку, он попадает в сохраненный процесс, который помогает приложению решить, следует ли разрешить пользователю изменять его.

Надеюсь, это имеет смысл....

Ответ 3 · рейтинг 3 · Slee

Я сделал что-то подобное, когда пользователь открыл тикет (строку), он назначил этот тикет этому пользователю и установил значение в этой записи, например, и FK для этого конкретного пользователя, поэтому, если кто-то еще пытался открыть этот тикет (строку), он сообщит им, что он уже был назначен кому-то другому.

Ответ 4 · рейтинг 2 · Daniel Auger

Если возможно, ограничьте систему, чтобы они просто получали следующую открытую проблему из рабочей очереди, а не имели возможность выбирать из всех открытых проблем.

Если это невозможно, я полагаю, вы могли бы проверить при выборе проблемы, чтобы узнать, доступна ли она. Если он недоступен, сделайте так, чтобы он исчез после того, как пользователь нажмет на него. Таким образом, вы запрашиваете только тогда, когда они действительно нажимают на что-то, а не на постоянный опрос данных.

Ответ 5 · рейтинг 2 · tvanfosson

Пробовали ли вы увеличить время между обновлениями. Я ожидаю, что одного раза в 30 секунд будет достаточно. 40 запросов в минуту - это намного меньше нагрузки, чем 1200 в минуту. Ваши пользователи могут даже не заметить разницы.

Если они это сделают, как насчет того, чтобы добавить кнопку обновления на страницу, чтобы пользователи могли вручную обновить список непосредственно перед выбором элемента, чтобы избежать раздражающего сообщения, если они выберут.

Ответ 6 · рейтинг 1 · eglasius

Я не вижу проблемы, особенно после того, как вы упомянули, что уже помечаете заявки как находящиеся в процессе/поддерживаемом состоянии и имеете отметку времени/версию элемента.

Разве недостаточно следующего:

  1. Пользователь просматривает билеты и видит список доступных билетов, то есть это исключает те, которые находятся в базе данных в процессе обработки. Если вы хотите, чтобы пользователи также видели незавершенные заявки, вы четко указываете это в статусе заявки и отключаете возможность ее получения.
  2. Пользователь либо помечает тикет как работающий явно, либо неявно, открывая тикет (зависит от пользовательского опыта/как он представлен пользователям).
  3. Пользователь явно переводит заявку в другой статус, т. е. завершена, недействительна, ожидает отзыва и т. д.

Когда элементы извлекаются в 1, вы включаете метку времени/версию. Когда происходит 2, вы используете оптимистичный подход параллелизма, чтобы убедиться, что если 2 человека попытаются обновить билет одновременно, только первый из них будет успешным.

Что произойдет, так это то, что для второго человека обновление ... где ... временная метка = @timestamp не найдет никаких записей для обновления, и вы сообщите, что билет уже был принят.

Если вы хотите, вы можете использовать вышеперечисленное, чтобы обновлять пользовательский интерфейс по мере захвата билетов. Это может быть просто полное обновление текущей страницы билетов через x раз (возможно, предупреждение/подсказка пользователю) или даже получение списка билетов, измененных для страницы билетов, отображаемой с помощью ajax. У вас все еще есть предыдущие шаги, так как эта модификация предназначена только для удобства пользователей.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы