Середина уровневой необходимой справки

В одном предложении, что я в конечном счете должен знать, то, как совместно использовать объекты между серединой уровневых функций w/требующий уровню приложений к передать объекты модели данных.

Я работаю над созданием середины уровневого слоя в нашей текущей среде для компании, на которую я работаю. В настоящее время мы используем, прежде всего.NET для программирования и создали пользовательские модели данных вокруг всех наших различных систем баз данных (в пределах от Oracle, OpenLDAP, MSSQL и других).

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

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

main
 {
  MidTierServices.UpdateCustomerName("testaccount", "John", "Smith");

  // since the data takes up to 4 seconds to be replicated from
  // write server to read server, the function below is going to
  // grab old data that does not contain the first name and last
  // name update....  John Smith will be overwritten w/ previous
  // data

  MidTierServices.UpdateCustomerPassword("testaccount", "jfjfjkeijfej");
 }

 MidTierServices
 {
  void UpdateCustomerName(string username, string first, string last)
  {
   Customer custObj = DataRepository.GetCustomer(username);

   /*******************
   validation checks and business logic go here...
   *******************/

   custObj.FirstName = first;
   custObj.LastName = last;

   DataRepository.Update(custObj);
  }

  void UpdateCustomerPassword(string username, string password)
  {
   // does not contain first and last updates
   Customer custObj = DataRepository.GetCustomer(username); 

   /*******************
   validation checks and business logic go here...
   *******************/

   custObj.Password = password;

   // overwrites changes made by other functions since data is stale
   DataRepository.Update(custObj); 
  }
 }

На ноте стороны возможности, которые я рассмотрел, создают слой кэширования собственной разработки, который занимает много времени и является очень трудным понятием для продажи управлению. Используйте другой слой моделирования, который создал в кэширующейся поддержке, такой как nHibernate: Это также было бы трудно продать управлению, потому что эта опция также займет очень долгое время, разрывают нашу всю пользовательскую модель и заменяют его w/решение других производителей. Кроме того, не много поставщиков поддерживает наш большой массив баз данных. Например.NET имеет LINQ к ActiveDirectory, но не LINQ к OpenLDAP.

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

Править

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

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

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

5
задан regex 22 January 2010 в 00:10
поделиться

1 ответ

Вы описываете очень распространенную проблему.

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

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

Проблема

Возможна, когда есть несколько авторов, что чтение + часть записи двух обновлений становится чередуется. Предположим, у вас есть A и B, оба из которых прочитаны, а затем обновите ту же строку в базе данных. A Читает базу данных, затем B считывает базу данных, то B обновляет ее, то обновляет его. Если у вас есть наивный подход, то «последняя запись» выиграет, и пишеты B могут быть уничтожены.

Введите оптимизм параллелизма. Основная идея состоит в том, чтобы полагаться, что обновление будет работать, но проверьте. Вроде как доверие , но проверяйте подход к контролю над вооружением из нескольких лет назад. Способ сделать это - включить поле в таблице базы данных, которая должна также быть включена в объект домена, который обеспечивает способ отличить одну «версию» строки DB или объекта домена из другого. Самый простой состоит в том, чтобы использовать поле Timestamp, названное LastUpdate, который содержит время последнего обновления. Есть другие более сложные способы сделать проверку согласованности, но поле Timestamp - это хорошо для иллюстрации.

Затем, когда писатель или Updater хочет обновить БД, он может обновлять только строку, для которой ключ совпадает (независимо от вашей клавиши) , а также , когда ящики Lastupdate. Это версия.

Поскольку разработчики понимают код, я предоставлю некоторых псевдо-SQL. Предположим, у вас есть база данных блога, с индексом, заголовком и некоторым текстом для каждого входа в блоге. Вы можете получить данные для набора строк (или объектов), таких как это:

SELECT ix, Created, LastUpdated, Headline, Dept FROM blogposts 
    WHERE CONVERT(Char(10),Created,102) = @targdate 

Этот вопрос может извлечь все сообщения блога в базе данных в течение определенного дня или месяца, или что-то еще.

С помощью простого оптимистического параллелизма вы бы обновили единую строку с использованием SQL Allughtive:

UPDATE blogposts Set Headline = @NewHeadline, LastUpdated = @NewLastUpdated
    WHERE ix=@ix AND LastUpdated = @PriorLastUpdated

Обновление может произойти только в том случае, если индексные совпадения (и мы предполагаем, что это первичный ключ), а также в Lastupdated Поле то же самое, что было, когда данные были прочитаны. Также обратите внимание, что вы должны обеспечить обновление последнего поля для каждого обновления до строки.

Более строгое обновление может настаивать на том, что ни одна из колонн не обновлялась. В этом случае вообще нет метки времени. Что-то вроде этого:

UPDATE Table1 Set Col1 = @NewCol1Value,
              Set Col2 = @NewCol2Value,
              Set Col3 = @NewCol3Value
WHERE Col1 = @OldCol1Value AND
      Col2 = @OldCol2Value AND
      Col3 = @OldCol3Value

Почему это называется «оптимистичным»?

OCC используется в качестве альтернативы удерживанию блокировков базы данных, который является жестким подходом для сохранения согласованных данных. Блокировка БД может предотвратить чтение от чтения или обновления строки БД, пока она удерживается. Это, очевидно, имеет огромные последствия производительности. Так что act ослабляет это, и действует «оптимистично», предполагая, что когда приходит время обновления, данные в таблице не будут обновлены в то же время. Но, конечно, это не слепой оптимизм - вы должны проверить прямо перед обновлением.

Использование оптимистичной какургеры на практике

Вы сказали, что используете .NET. Я не знаю, используете ли вы наборы данных для вашего доступа к данным, сильно напечатанным или иным образом. Но .NET DataSets, или в частности даматисты, включают встроенную поддержку для OCC. Вы можете указать и поправить вручную updateCommand для любого dataadapter, и именно здесь вы можете вставить проверку согласованности. Это также , возможно в рамках опыта дизайна Visual Studio .

alt text
(Источник: ASP.NET )

Если вы получаете нарушение, обновление вернет результат, показывающий, что нулевые строки были обновлены. Вы можете проверить это в Dataadapter.Rowupdated событие . (Будьте в курсе, что в модели ADO.NET есть другой DataDapter для каждой базы данных. Ссылка есть для SQLDataAdapter, которая работает с SQL Server, но вам понадобится другой DA для разных источников данных.)

В событии rowupdated вы можете проверить количество строк, которые были затронуты, а затем предпринять некоторые действия, если счет равен нулю.


Сводка

Убедитесь, что содержимое базы данных не было изменено, перед записью обновления. Это называется оптимистичный контроль параллелизма .


Другие ссылки:

3
ответ дан 15 December 2019 в 06:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: