Session: 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.
Checks can be turned on by setting UseOptimisticConcurrency
property from Advanced
session operations to true
and may cause ConcurrencyExceptions
to be thrown.
Example I
using (IDocumentSession session = store.OpenSession())
{
// Enable optimistic concurrency for this session
session.Advanced.UseOptimisticConcurrency = true;
// Save a document in this session
Product product = new Product { Name = "Some Name" };
session.Store(product, "products/999");
session.SaveChanges();
// Modify the document 'externally' by another session
using (IDocumentSession otherSession = store.OpenSession())
{
Product otherProduct = otherSession.Load<Product>("products/999");
otherProduct.Name = "Other Name";
otherSession.SaveChanges();
}
// Trying to modify the document without reloading it first will throw
product.Name = "Better Name";
session.SaveChanges(); // This will throw a 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 convention DefaultUseOptimisticConcurrency
.
Example II
// Enable for all sessions that will be opened within this document store
store.Conventions.UseOptimisticConcurrency = true;
using (IDocumentSession session = store.OpenSession())
{
bool isSessionUsingOptimisticConcurrency = session.Advanced.UseOptimisticConcurrency; // will return true
}
Remarks
When Optimistic Concurrency is used with Replication then we advise to set ForceReadFromMaster
when only read operations are load-balanced (FailoverBehavior.ReadFromAllServers) and you want to perform document update.
using (IDocumentSession session = store.OpenSession())
{
// Store document 'products/999'
session.Store(new Product { Name = "Some Name" }, id: "products/999");
session.SaveChanges();
}
using (IDocumentSession session = store.OpenSession())
{
// Enable optimistic concurrency for the session
session.Advanced.UseOptimisticConcurrency = true;
// Store the same document
// Pass 'null' as the changeVector to turn OFF optimistic concurrency for this document
session.Store(new Product { Name = "Some Other Name" }, changeVector: null, id: "products/999");
// This will NOT throw a ConcurrencyException, and the document will be saved
session.SaveChanges();
}