I have a simple application that must assign a sequential number without gaps or duplicates to each Document
that is created i.e. 1, 2, 3 etc. A different document type will have a different numering sequence.
DocumentTypes
is a database table which stores the different types of documents e.g. Book, Recipe, WhitePaper
Documents
is a database table which stores the document info including its sequential ID
The database relationship is one DocumentType
can have many Documents
but each Document
will have only one DocumentType
If DocumentType.LastNumber
holds the last number assigned for a particular document type, my plan was:
// create a transaction to lock the DocumentType row being assigned so no duplicates
var transaction = dbContext.Database.BeginTransaction(IsolationLevel.Serializable);
// get the appropriate document type from the db
var documentType = dbContext.DocumentTypes.Single(t => t.Id == 1);
// increment the last document number
documentType.LastNumber++;
// create the new document with the new number
documentType.Documents.Add(new Document{
Id = documentType.LastNumber
});
dbContext.SaveChanges();
// commit the transaction and release the db lock
transaction.Commit();
However, what Im finding is that I get duplicate numbers for a given document type (when I call this method asynchronously via API)
I suspect I have misunderstood how database transactions and IsolationLevel.Serializable
work. Any feedback would be greatly appreciated.