When using RavenDB in the context of a web application we should not open RavenDB's session for every operation of the database. Session should rather be opened for every Request/Response cycle(every button click for example).
A way to do that is to open RavenDB's
Application_Start, open a new session in
Application_BeginRequest and close the session at
Application_EndRequest events of your application’s Global.asax file:
In the case of ASP.NET MVC we are going to have BaseController - the one that all controllers inherit from. In the Base Controller we have:
When we need to do something and use the session in a controller that inherits from BaseController:
This way of defining and using RavenDB’s session makes the use of the session decoupled from the opening and closing of the session and also decoupled from the Document Store. The approach is very good for scenarios where we want to use the same controllers outside the scope of the current web application – for example in a Unit Testing project.
Some time ago I had a small issue with RavenDB master-master replication which ended up in creating 50 000 conflicted documents on a live database It all ended fine but I had a little hard time of finding info on how to fix that kind of issue ‘fast’. Don’t get me wrong – there is a very nice RavenDB documentation about replication and conflicts but I didn’t find a fast-and-easy solution(one that involved couple of clicks in Raven’s studio) and I was a little disappointed about that. Guess RavenDB makes you little spoiled.
Anyway, here’s my solution:
1. First, you create an RavenDB index(you can create it through the studio):
Let’s name it ConflictsIndex. This index extracts all the documents of a database in an index so you could query them.
2. Then you Execute it to see the results.
Don’t worry if there are no results at first. If you have large amount of data and large amount of conflicted documents – RavenDB would need some time to index them all. During that time you could:
3. Create an Console app that fixes the conflicts of the documents.
This console app will load all the documents from the currently created index in batches of 1000(usually RavenDB has a default limit 1024 items per select so we use 1000). While loading the documents if there are any conflicts, they will be automatically fixed with the TakeNewestConflictResolutionListener. This listener chooses always the last document to be the resolved one. If you need different custom logic for resolving the conflicts – the listener is the place to insert your code.
4. Execute the console application on the database. You could wait for the ConflictsIndex to finish indexing and run the console app. If the database is a remote one(most production databases are) – you could copy the console app on some PC that is in the LAN of the PC with the database so the process would be faster.
Also it’s good to put a default Conflict Resolution Listener in your application if you don’t have one. Just in case. If you don’t have one – every time you try to load a conflicted document - an exception is thrown, so the situation could get pretty heated pretty fast.
And that’s it. Usually you shouldn't get to situations like that but when you do - it’s good to know how you can get out of them.