lucamilan
4/27/2012 - 12:55 PM

Sequential Number Generator for RavenDB

Sequential Number Generator for RavenDB

private static readonly object GeneratorLock = new object();

///<summary>
/// Create the next id (numeric)
///</summary>
private int NextAccountNumber()
{
	lock (GeneratorLock)
	{
		using (new TransactionScope(TransactionScopeOption.Suppress))
		{
			while (true)
			{
				try
				{
					var document = GetDocument();
					if (document == null)
					{
						PutDocument(new JsonDocument {
							Etag = Guid.Empty, // sending empty guid means - ensure the that the document does NOT exists
							Metadata = new RavenJObject(),
							DataAsJson = RavenJObject.FromObject(new { Current = 1000 }),
							Key = "Raven/InvoiceNumber"
						});
						return 1000;
					}

					int current;
					current = document.DataAsJson.Value<int>("Current");
					current++;

					document.DataAsJson["Current"] = current;
					PutDocument(document);

					return current;
				}
				catch (ConcurrencyException)
				{
					// expected, we need to retry
				}
			}
		}
	}
}

private void PutDocument(JsonDocument document)
{
	DocumentStore.DatabaseCommands.Put(
		"Raven/InvoiceNumber", 
		document.Etag,
		document.DataAsJson,
		document.Metadata);
}

private JsonDocument GetDocument()
{
	return DocumentStore.DatabaseCommands.Get("Raven/InvoiceNumber");
}