I solved my problem. Previously I used session.Lock(entity, LockMode.Upgrade);, but that throws an StaleObjectStateException, but instead, if I used session.QueryOver<POCO>().Lock().Upgrade...; it works fine. I suppose that the lock was set to late in the first case, so the exception was thrown.
Thanks again for everything :). El domingo, 17 de abril de 2016, 9:46:39 (UTC-3), Quicoli escribió: > > Hi, > > I believe getlastunusedfolio should lock your table and your transction > scope should be something like lock and wait. > > This way the first one in, lock the access and the subsequent requests > keep waiting for the first one to finish... > > This is an idea... > Em 17/04/2016 07:18, "Nicolás Mancilla" <[email protected] > <javascript:>> escreveu: > >> Hello Everyone! >> >> I have a question regarding concurrent requests. >> >> I have an two entities: >> >> class Document { >> >> FolioNumber // Long/bigint >> other_properties... >> >> } >> >> class FolioRange { >> >> CurrentFolio // Long/bigint >> Start // The first folio in the range >> End // The last folio in the range >> IsUsed // When the CurrentFolio >= End >> DateCreated >> IsCurrentRange >> >> DocumentType >> RangeStatus >> >> } >> >> (Imagine that these are valid POCOs please :) >> >> Every time a Document is inserted to the database, the >> Document.FolioNumber is set to the FolioRange.CurrentFolio. The logic is >> this: >> >> public long GetNextFolioNumber(string documentType, Tenant tenant) >> { >> // Check if there is a folio range defined >> var entity = session.QueryOver<FolioRange>() >> .Where( >> i => >> i.Tenant.Id == tenant.Id && i.DocumentType == >> documentType && i.IsCurrentRange && >> i.Status == RangeStatus.Enabled) >> .Take(1) >> .SingleOrDefault(); >> if (entity == null) >> { >> return 0; >> } >> >> // Retrieve an unused folio, if there are any >> var folio = GetLastUnusedFolio(entity); >> if (folio > 0) >> { >> return folio; >> } >> >> FolioRange range; >> >> // If the folio range has no folios left, >> // try to change to the newest folio range >> if (entity.IsUsed) >> { >> log.InfoFormat( >> "The folio range '{0}' has been consumed. Trying to >> switch to the next one (if there is one).", >> entity.Id); >> // Update the old folio range to disable it >> entity.IsCurrentRange = false; >> entity.Status = RangeStatus.Disabled; >> session.Update(entity); >> range = session.QueryOver<FolioRange>() >> .Where( >> i => >> i.Tenant.Id == tenant.Id && i.DocumentType == >> documentType && >> i.CreatedDate > entity.CreatedDate) >> .Take(1) >> .SingleOrDefault(); >> >> // If there is no newest folio range, return >> if (range == null) >> { >> return 0; >> } >> >> log.InfoFormat("Successfully switched to folio range >> '{0}'.", entity.Id); >> // If there was a newest folio range, update it. >> range.IsCurrentRange = true; >> range.Status = RangeStatus.Enabled; >> } >> else >> { >> log.InfoFormat("Using folio range '{0}'; Current folio: >> {1}", entity.Id, entity.CurrentFolio); >> range = entity; >> } >> >> // Set the current folio as result and increment the current >> folio. >> folio = range.CurrentFolio; >> range.CurrentFolio++; >> session.Update(range); >> return folio; >> } >> >> >> This works well when there is only 1 request, but when there are more than >> 1, then there is a race condition when the range.CurrentFolio++ is not >> updated and two Documents get created with the same folio number, which is >> not allowed. >> >> >> I've tried using session.Lock(range, LockMode.Upgrade), without luck (a >> UNIQUE KEY Violation is triggered). The Session.Transaction isolation level >> is ReadCommited. >> >> >> I'm using NHibernate 4.0.4 and Nancy 1.4.3. >> >> >> Any suggestions, book references or any reading will be greatly appreciated. >> >> >> Thanks! >> >> -- >> You received this message because you are subscribed to the Google Groups >> "nhusers" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> To post to this group, send email to [email protected] >> <javascript:>. >> Visit this group at https://groups.google.com/group/nhusers. >> For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "nhusers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/nhusers. For more options, visit https://groups.google.com/d/optout.
