Как использовать дополнительные многопользовательские обновления с помощью NHibernate - PullRequest
2 голосов
/ 28 июля 2010

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

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

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

Если другой пользователь сделал другие записи по тем же элементам, сальдо, с которыми работает первый пользователь, теперь недействительны. Я знаю, что при попытке сохранения NHibernate выдаст исключение устаревших данных. Но это не то, что я хочу, так как одновременные обновления являются необходимостью. Я хочу, чтобы текущий баланс элемента увеличивался или уменьшался в зависимости от количества записей. Или что элемент будет извлечен снова во время обновления, заблокирован, произведен пересчет, а затем, наконец, обновлен, но я не знаю, как этого можно достичь в этом сценарии и где именно находится код. Я хотел бы избежать его нахождения в доменном объекте, поскольку управление пессимистической блокировкой и т. Д. Является проблемой приложения / постоянства. Кажется, это должен быть распространенный сценарий, но я не видел, чтобы что-то обсуждало это.

P.S. У меня есть еще одно беспокойство о том, как подход refetch-lock-recalculate-update я описал выше в ситуации, когда запись имеет много строк. Будут ли отправляться отдельные запросы на блокировку для каждого элемента или есть способ получить блокировки для всех элементов строк ввода за один раз.

Любая помощь будет оценена.

class TestConcurrentUpdates
{ 
   ISession session; 
   Entry entry; 
   ItemRepository itemRep; 
   EntryRepository entryRep; 

   void testMethod()
   {
       ...

       Entry entry = new Entry();

       Item item1 = itemRepository.Get(item1ID); 
       Item item2 = itemRepository.Get(item1ID); 
       Item item3 = itemRepository.Get(item1ID); 

       entry.Lines.Add(new EntryLine(this, item1, 10)); 
       entry.Lines.Add(new EntryLine(this, item2, -4)); 
       entry.Lines.Add(new EntryLine(this, item3, 2)); 
       using (ITransaction transaction = session.BeginTransaction()) 
       { 
           entryRep.Save(entry); 
           transaction.Commit(); 
       } 
   }
} 


Item 
{ 
   string name; 
   double balance; 
   IList<EntryLine> entries = new List<EntryLine>(); 

   public double getBalance() { return balance; } 


   void addEntryLine(EntryLine line) 
   { 
       entries.add(line); 
       balance += line.getQuantity(); 
   } 
} 


class Entry 
{ 
   IList<EntryLine> lines = new List<EntryLine>(); 
   public IList<EntryLine> Lines { get { return lines; } } 
} 

class EntryLine 
{ 
   Entry entry; 
   double quantity; 
   Item item; 
   public EntryLine(Entry entry, Item item, double quantity) 
   { 
       this.entry = entry; 
       this.quantity = quantity; 
       this.item = item; 
       item.addEntryLine(this); 
   } 

   public double getQuantity() 
   { 
       return quantity; 
   } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...