Great Nicolás! I was about to suggest you that Lock().Upgrade() when I got your successful feedback :)
2016-04-17 18:50 GMT-03:00 Nicolás Mancilla < [email protected]>: > 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]> >> 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]. >>> 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. >>> >> -- > 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. > -- 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.
