How to enable optimistic concurrency?
By default, optimistic concurrency checks are turned off, which means that changes made outside our session object will be overwritten if the SaveChangesAsync
is called.
Checks can be turned on by setting the UseOptimisticConcurrency
property from the Advanced
session operations to true
and may cause the ConcurrencyExceptions
to be thrown.
Example I
using (IAsyncFilesSession session = store.OpenAsyncSession())
{
session.Advanced.UseOptimisticConcurrency = true;
session.RegisterUpload("ravendb.exe", content, new RavenJObject { { "Copyright", "hibernatingrhinos.com"}});
await session.SaveChangesAsync();
using (IAsyncFilesSession otherSession = store.OpenAsyncSession())
{
FileHeader fileInOtherSession = await otherSession.LoadFileAsync("ravendb.exe");
fileInOtherSession.Metadata["Copyright"] = "Hibernating Rhinos LTD";
await otherSession.SaveChangesAsync();
}
FileHeader file = await session.LoadFileAsync("ravendb.exe");
session.RegisterUpload(file, newContent);
await session.SaveChangesAsync(); // will throw ConcurrencyException
}
The above example shows how to enable optimistic concurrency for a particular session. However, that can be also turned on globally, that is for all opened sessions, by using the DefaultUseOptimisticConcurrency
convention.
Example II
store.Conventions.DefaultUseOptimisticConcurrency = true;
using (IAsyncFilesSession session = store.OpenAsyncSession())
{
bool isSessionUsingOptimisticConcurrency = session.Advanced.UseOptimisticConcurrency; // will return true
}
Example III
You can also force the concurrency check by explicitly passing an Etag
parameter to the RegisterXXX
method.
using (IAsyncFilesSession session = store.OpenAsyncSession())
{
FileHeader file = await session.LoadFileAsync("git.exe");
session.RegisterFileDeletion(file, file.Etag);
await session.SaveChangesAsync();
}