RavenDB continues to throw ConcurrencyException

I keep getting ConcurrencyException, trying to update the same document several times in a row. PUT attempted on document '<id>' using a non current etag is a message.

Each time we save our user interface, we publish an event using MassTransit. This event is sent to subscription tickets, but I turned off Eventhandlers offline (testing offline subscribers). After the event handler enters the network, the queue is read and messages are processed as intended.

However, since the same object is queued several times, the first record succeeds, the next does not, and throws this concurrencyexception condition.

I use the factory class to have compatible IDocumentStore and IDocumentSession in all my applications. I specifically set UseOptimisticConcurrency = false in the GetSession () method.

 public static class RavenFactory { public static IDocumentStore CreateDocumentStore() { var store = new DocumentStore() { ConnectionStringName = "RavenDB" }; // Setting Conventions store.Conventions.RegisterIdConvention<MyType>((db, cmd, e) => e.MyProperty.ToString()); store.Conventions.RegisterAsyncIdConvention<MyType>((db, cmd, e) => new CompletedTask<string>(e.MyProperty.ToString())); // Registering Listeners store .RegisterListener(new TakeNewestConflictResolutionListener()) .RegisterListener(new DocumentConversionListener()) .RegisterListener(new DocumentStoreListener()); // Initialize and return store.Initialize(); return store; } public static IDocumentSession GetSession(IDocumentStore store) { var session = store.OpenSession(); session.Advanced.UseOptimisticConcurrency = false; return session; } } 

The event handler is as follows. IDocumentSession is injected using Injection Dependency. Here is the logic for getting an instance of IDocumentSession.

 private static void InitializeRavenDB(IUnityContainer container) { container.RegisterInstance<IDocumentStore>(RavenFactory.CreateDocumentStore(), new ContainerControlledLifetimeManager()); container.RegisterType<IDocumentSession, DocumentSession>(new PerResolveLifetimeManager(), new InjectionFactory(c => RavenFactory.GetSession(c.Resolve<IDocumentStore>()))); } 

And here is the actual EventHandler that has a ConcurrencyException.

 public class MyEventHandler:Consumes<MyEvent>.All, IConsumer { private readonly IDocumentSession _session; public MyEventHandler(IDocumentSession session) { if (session == null) throw new ArgumentNullException("session"); _session = session; } public void Consume(MyEvent message) { Console.WriteLine("MyEvent received: Id = '{0}'", message.MyProperty); try { _session.Store(message); _session.SaveChanges(); } catch (Exception ex) { var exc = ex.ToString(); // Deal with concurrent writes ... throw; } } } 

I want to ignore any concurrencyexception so far until we can figure out the business of how to solve concurrency.

So, any ideas why I get a ConcurrencyException? I want the save to happen regardless of whether the document was updated before or after.

+4
source share
1 answer

I am not familiar with setting up Unity, but you always want Singleton from IDocumentStore . Below, I encoded Singleton manually, but I'm sure Unity will support it:

 public static class RavenFactory { private static IDocumentStore store; private static object syncLock = new object(); public static IDocumentStore CreateDocumentStore() { if(RavenFactory.store != null) return RavenFactory.store; lock(syncLock) { if(RavenFactory.store != null) return RavenFactory.store; var localStore = new DocumentStore() { ConnectionStringName = "RavenDB" }; // Setting Conventions localStore .Conventions.RegisterIdConvention<MyType>((db, cmd, e) => e.MyProperty.ToString()); localStore .Conventions.RegisterAsyncIdConvention<MyType>((db, cmd, e) => new CompletedTask<string>(e.MyProperty.ToString())); // Registering Listeners localStore .RegisterListener(new TakeNewestConflictResolutionListener()) .RegisterListener(new DocumentConversionListener()) .RegisterListener(new DocumentStoreListener()); // Initialize and return localStore.Initialize(); RavenFactory.store = localStore; return RavenFactory.store; } } // As before // public static IDocumentSession GetSession(IDocumentStore store) // } 
0
source

Source: https://habr.com/ru/post/1494433/


All Articles