concurrency - RavenDB keeps throwing a ConcurrencyException -
i keep getting concurrencyexception trying update same document multiple times in succession. put attempted on document '<id>' using non current etag
message.
on every save our ui publish event using masstransit. event sent subscriberqueues, put eventhandlers offline (testing offline subscribers). once eventhandler comes online queue read , messages processed intended.
however since same object in queue multiple times first write succeeds, next doesn't , throws concurrencyexception.
i use factory class have consistent idocumentstore , idocumentsession in applications. set useoptimisticconcurrency = false
in 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 , return store.initialize(); return store; } public static idocumentsession getsession(idocumentstore store) { var session = store.opensession(); session.advanced.useoptimisticconcurrency = false; return session; } }
the eventhandler looks this. idocumentsession gets injected using dependency injection. here logic 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 actual eventhandler has 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 concurrent writes ... throw; } } }
i want ignore concurrencyexception until can sort out business on how tackle concurrency.
so, ideas why concurrencyexception? want save happen no matter whether document has been updated before or not.
i unfamiliar configuring unity, want singleton of idocumentstore
. below, have coded singleton out manually, i'm sure unity 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 , return localstore.initialize(); ravenfactory.store = localstore; return ravenfactory.store; } } // before // public static idocumentsession getsession(idocumentstore store) // }
Comments
Post a Comment