Strategy for generating unique identifier for document in RavenDB -
say have support ticket system (simplified example). has many users , organizations. each user can member of several organizations, typical case 1 org => many users, , of them belong organization. each organization has "tag" used construct "ticket numbers" organization. lets have org called stackexchange wants tag ses.
so if open first ticket of today, want ses140407-01
. next ses140407-02
, on. doesn't have 2 digits after dash.
how can make sure generated in way makes sure 100% unique across organization (no orgs have same tag)?
note: not have document id in database - guid or similar. ticket reference - kinda slug - appear in related emails etc. has unique, , prefer if didn't "waste" sequential case numbers hilo style.
is there practical way ensure unique ticket number if 2 or more people report new 1 @ same time?
edit: each organization document in ravendb
, , can hold property lastissuedticketid
. challenge find best way read field, generate new one, , store in way "race condition safe".
another edit: clear - intend generate ticket id in own software. looking way ask ravendb "what last ticket number", , when generate next 1 after that, "am 1 using this?" - give ticket unique case id, not related ravendb considers document id.
i use generic sequence generator written ravendb:
public class sequencegenerator { private static readonly object lock = new object(); private readonly idocumentstore _docstore; public sequencegenerator(idocumentstore docstore) { _docstore = docstore; } public int getnextsequencenumber(string sequencekey) { lock (lock) { using (new transactionscope(transactionscopeoption.suppress)) { while (true) { try { var document = getdocument(sequencekey); if (document == null) { putdocument(new jsondocument { etag = etag.empty, // sending empty guid means - ensure document not exists metadata = new ravenjobject(), dataasjson = ravenjobject.fromobject(new { current = 0 }), key = sequencekey }); return 0; } var current = document.dataasjson.value<int>("current"); current++; document.dataasjson["current"] = current; putdocument(document); { return current; } } catch (concurrencyexception) { // expected, need retry } } } } } private void putdocument(jsondocument document) { _docstore.databasecommands.put( document.key, document.etag, document.dataasjson, document.metadata); } private jsondocument getdocument(string key) { return _docstore.databasecommands.get(key); } }
it generates incremental unique sequence based on sequencekey
. uniqueness guaranteed raven optimistic concurrency based on etag. each sequence has own document update when generate new sequence number. also, there lock
reduced db calls if several threads executing @ same moment @ same process (appdomain).
for case can use way:
var sequencekey = string.format("{0}{1:yymmdd}", yourcompanyprefix, datetime.now); var nextsequencenumber = new sequencegenerator(yourdocstore).getnextsequencenumber(sequencekey); var nextsequencekey = string.format("{0}-{1:00}", sequencekey, nextsequencenumber);
Comments
Post a Comment