лучшие практики для базы данных + параллелизм набора результатов (как пользовательский интерфейс, так и проблемы управления) - PullRequest
2 голосов
/ 01 мая 2009

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

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

Что мне интересно, Каковы подходящие шаблоны проектирования для базы данных и пользовательского интерфейса приложения, чтобы избежать проблем параллелизма?

Чтобы быть пуленепробиваемым, я мог бы заставить пользователя использовать явную транзакцию (например, большую часть времени он находится в режиме только для чтения, затем ему нужно нажать кнопку «Редактировать», чтобы начать транзакцию, затем кнопки «Подтвердить» и «Отменить», чтобы подтвердить фиксацию). или отменить транзакцию), но это кажется неуклюжим и не сработает с большими наборами изменений («Редактировать», тогда изменение за 1 час приводит к чрезмерно большой транзакции и может помешать другим людям вносить изменения). Кроме того, было бы плохо, если кто-то вносит кучу изменений, а затем это терпит неудачу - тогда что они должны делать, чтобы избежать потери этой работы?

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

Кроме того, если есть обновления, я должен автоматически перенести их на дисплей приложения? (при условии, что они не затирают то, над чем работает пользователь) Или пользователь должен быть явно обновлен?

Отличным примером, который близок к ситуации, над которой я работаю, являются исследователи файловых систем (например, Windows Explorer), которые показывают иерархию папок / каталогов и список объектов внутри них. Проводник Windows позволяет вам обновлять, но есть также некоторое уведомление от файловой системы к окну Проводника, так что, если новый файл будет создан, он просто появится в окне просмотра без необходимости нажимать клавишу F5 для обновления.

Я нашел эти сообщения в StackOverflow, но они не совсем совпадают:

Ответы [ 3 ]

1 голос
/ 30 сентября 2009

хороший рабочий способ, которым я пользуюсь: не открывайте tran, пока действительно не примените изменения в БД (после того, как пользователь нажмет кнопку Сохранить) даже не нужно обновлять запись перед началом редактирования пользователем. но непосредственно перед применением изменений проверьте, не изменилась ли запись другим пользователем в коде вашего приложения. это делается с помощью оператора select непосредственно перед оператором update. если запись со старыми значениями полей (в DataSet) не существует в базе данных, предупредите пользователя, что «запись изменена другим пользователем», и пользователь должен закрыть диалог, обновить запись и снова начать редактирование. остальное открой транс и остальное.

1 голос
/ 01 мая 2009
  1. Одновременно отображается только одна запись для редактирования.

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

Это самый простой и надежный из известных мне шаблонов. Попытки побудить пользователя явно выбрать режим «Отображение» или «Редактировать» проблематичны. Он блокирует запись на неопределенное количество времени, и не всегда надежно, что вы знаете, когда пользователь (например) сдается, выключает компьютер и уходит домой.

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

0 голосов
/ 02 мая 2009

Оптимистическая блокировка отлично работает в большинстве случаев, когда ваши записи состоят из коротких простых полей (например, короткая строка или одно числовое значение на поле), предоставляя пользователям максимальный доступ к данным и не заставляя их беспокоиться о блокировках и прочее. Применяйте блокировку записи только в процессе сохранения записи. Никакие записи не заблокированы, пока кто-то просто редактирует. Если приложение находит запись, которую пытается сохранить, уже заблокировано, то приложение просто повторяет попытку через короткое время (<500 мс). Нет необходимости предупреждать пользователя (кроме, может быть, обратной связи с песочными часами / указателем, если она длится дольше 500 мс), так как никакой блокировки никогда не было достаточно долго, чтобы иметь значение для пользователя. Когда пользователь A сохраняет запись, база данных обновляет только те поля, которые пользователь A изменил (вместе с любыми другими полями, которые зависят от этих измененных значений). Это позволяет избежать перезаписи старыми значениями полей, измененных пользователем B, так как пользователь A получил запись. </p>

Неявное предположение состоит в том, что тот, кто редактирует поле записи в последний раз, имеет последнее слово, что не является неразумным способом ведения бизнеса. Например, пользователь A извлекает запись и редактирует поле, затем пользователь B извлекает запись и редактирует то же поле. Пользователь B сохраняет, затем Пользователь A сохраняет. Изменения пользователя A перезаписывают пользователя B. Работа пользователя B была «пустой тратой», но такого рода вещи произойдут в любом случае, когда пользователи будут обмениваться данными. Блокировки могут предотвратить бесполезную работу, когда пользователи пытаются отредактировать одну и ту же запись за один и тот же промежуток времени. Тем не менее, более вероятным случаем является то, что пользователь B редактирует поле записи и сохраняет его, затем пользователь A редактирует поле и сохраняет его, снова тратя впустую работу пользователя B. Вы не можете ничего сделать с замками, чтобы предотвратить это. Если на самом деле существует большая вероятность бесполезной работы при взаимодействии с пользователем, лучше предотвратить ее путем разработки бизнес-процесса, а не блокировок базы данных.

Что касается пользовательского интерфейса, я рекомендую два стиля сервера: (1) реальное время и (2) транзакционный.

  • В стиле реального времени пользовательские дисплеи автоматически соответствуют, насколько это практически возможно, тому, что находится в базе данных. Обновления выполняются автоматически либо на основе короткого периода (каждые пять секунд), либо «отправляются» пользователю, когда изменения вносятся другими. Когда пользователь вводит поле и выполняет редактирование, приложение подавляет обновления для этого поля, но продолжает обновлять другие поля и записи. Нет кнопки Сохранить или пункта меню. Приложение сохраняет запись каждый раз, когда пользователь редактирует поле, а затем покидает его или нажимает Enter. Когда пользователь начинает редактировать поле, приложение изменяет внешний вид поля, чтобы указать, что все является предварительным (например, изменение границы вокруг поля на пунктирную линию), чтобы побудить пользователя нажать Enter или Tab, когда закончите.

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

Как правило, в режиме реального времени япредпочтительнее Пользователям не нужно беспокоиться о устаревших данных или потерять много работы, забыв сохранить. Однако используйте Transactional, если необходимо поддерживать достаточную производительность базы данных. Возможно, вам не нужно Real Time, если обновление поля обычно занимает более 1,0 секунды для ответа сервера. Вам также следует учитывать Транзакционные транзакции, если пользовательские правки запускают основные события, которые трудно отменить или могут привести к потере работы (например, изменение значения бюджета вызывает уведомление об улучшении для утверждения). Явная команда Сохранить хороша для того, чтобы сказать: «Хорошо, я проверил свою работу, давай ее разорву».

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