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.

Reply via email to