#c# #asp.net
#c# #asp.net
Вопрос:
Я работаю над приложением, в котором многие сотрудники могут входить в систему для решения жалоб клиентов. Если один сотрудник нажимает кнопку «Пуск» для подачи жалобы, запись должна быть заблокирована. Под зависшим я подразумеваю, что он не должен отображаться на экране других сотрудников (когда экран обновляется на их компьютере с помощью Ajax). Далее это не должно появляться только в течение определенного периода времени. Если сотрудник не отвечает на жалобу в течение нескольких минут, она должна снова появиться в очереди жалоб.
Как мне управлять этой продолжительностью времени? У меня есть один подход, при котором пользователь нажимает «Пуск», я мог бы сохранить этот элемент в объекте кэша, и он действителен только до истечения срока его действия. Затем, когда экран другого сотрудника обновляется, я показываю только те элементы, которые не посещаются и не присутствуют в кэше. Если он присутствует в кэше, это означает, что его кто-то посещает. Я на правильном пути? Или есть какой-нибудь лучший способ сделать это?
Ответ №1:
Одна вещь, которую вы могли бы сделать, это иметь столбец ‘lock’ в базе данных, и пусть этот столбец будет столбцом DateTime.
Когда пользователь нажимает «Начать», обратите внимание на время в этом столбце.
При извлечении записей для отображения отфильтруйте все записи, которые имеют ненулевое значение в столбце блокировки, или значение которых в столбце блокировки было не менее x минут назад (которое вы можете вычислить с помощью математики в функции GetDate()).
Комментарии:
1. Неплохо. Мне понравилось решение. Самый элегантный, который я читал, не попадая в ненужные таймеры и т.д.
Ответ №2:
Самый простой способ сделать это — создать столбец с именем ‘RecordStatus’ или что-то в этом роде, которому вы можете присвоить специальное значение, чтобы указать, что он все еще создается или изменяется.
Это вынуждает вас изменять все ваши запросы, чтобы специально исключать записи с таким статусом, но в долгосрочной перспективе это работает лучше и надежнее, чем любой тип логических блокировок базы данных или уровня приложения.
Комментарии:
1. А что, если пользователь, который загружает запись, не освобождает ее? Как вы уведомляете базу данных об автоматическом освобождении записи в asp.net приложение, учитывая тот факт, что Session_End не гарантированно срабатывает? Я думаю, что ваш подход на правильном пути, но есть еще много дел…
2. Да, это всегда проблема. У нас есть пакетное задание, которое выполняется ежедневно, просматривает записи, которые были оставлены в режиме «черновик», и удаляет их.
3. Ваш ответ вдохновил меня также ответить. Хорошим решением для истечения срока действия блокировки на основе времени является то, что столбец блокировки должен быть DateTime (разрешать нули) вместо bool — затем вы можете получить на основе нулевой блокировки или блокировки, которая была установлена x минут назад.
Ответ №3:
Мы решили эту проблему в моей компании в двух ситуациях, независимо, используя некоторые изменения в записи базы данных «блокировка записи». В одной системе запись блокировки создается, когда запись попадает в «очередь» в качестве нового элемента; в другой системе запись блокировки создается, когда пользователь выбирает запись из очереди.
В любом случае, когда пользовательская копия вашего программного обеспечения открывает запись очереди для работы, в базе данных должна быть запись блокировки с некоторой уникальной информацией о вашем пользователе, записанной в нее. Он должен быть уникальным для блокируемой записи и, возможно, уровня блокировки (что означает, что две блокировки одного и того же уровня не могут существовать в одной записи) и идентифицирует пользователя, который открыл запись, как «владеющего» ею для целей внесения изменений. Эта запись блокировки должна сохраняться до тех пор, пока пользователь открывает запись в своем программном обеспечении.
Возможность «взламывать» блокировки может быть достигнута простым переназначением блокировки другому пользователю в сочетании с регулярным опросом объекта блокировки программным обеспечением исходного пользователя блокировки; если в любой момент пользователь больше не является владельцем, блокировка была «сломана», и у пользователя есть возможность повторно установить блокировку (взломав новую блокировку другого пользователя) или просто двигаться дальше.
Теперь, в случае сбоя программного обеспечения пользователя, они по-прежнему будут владеть блокировкой записи. Также может случиться, что операция по снятию блокировки завершится неудачно (это может произойти в ситуациях, когда реальные данные находятся в другой базе данных, и вы не можете принудительно выполнить универсальную транзакцию). В таком случае вам понадобится какой-либо механизм для удаления «потерянных» блокировок или принудительного удаления их пользователем. Если блокируемые элементы зависят от времени, вам нужно будет разработать несколько избыточных уровней удаления блокировки (возможно, задание по времени, которое раз в минуту снимает любую блокировку старше X минут или которая, как известно, «потеряна», потому что этот пользователь больше не входит в систему).