I have a http handler and I m storing every request to a concurrent queue collection in the memory. after a certain time, i m bulk inserting the collection to a database.
is this a bad idea? Because there is high volume, this seems to be a better approach IMO.
I do see some discrepancies (Number of hits vs number of stored elements in the db), due to threading, while i m flushing the concurrent collection, i m locking it and bulk insert its content and then empty the collection. then remove the lock from collection.
is there a better practice? or have you done a similar thing?
I have done pretty much exactly the same thing as you described with the code below. Its thread safe and has a flush method you could call to flush and pending writes. Once it reaches a threshold number of objects to write it sends the queue (List in my case) to a different thread for saving. Note that it uses a manualResetEvent to handle flushing the data at the end (there is a limit of 64 reset events that you can wait on, so that is why is manually waits if we have more than 64 background threads pending writing, but that should almost never happen unless your database is really slow). This code was used to process 10s of millions of records that were streamed into it (from memory it took about 5 mins to write 20m rows, but was running on save server as database, so no network hop…SQL can certainly handle thousands of rows a second using BulkSqlCopy object and IDataReader), so it should handle your request load (but of course that will depend on what you are writing and your database, but I think the code is up to the task!).
Also, to facility bulk writing I create a minimal implementation of an IDataReader to stream my data. You will need to do that for your reqests to use the code below.
The DataReaderFactory refered to below just selects the right IDataReader implmentation to use for streaming and looks as follows:
The data reader implementation that I used in this case (althoght this code will work with any data reader) is as follows:
Finally the bulk load data method looks as follows:
However, having said all that, I would recommend that you DO NOT use this code in asp.net for the reasons someone pointed out in another answer (particularly recycling of worker processes in IIS). I would suggest you use a very light weight queue to first send the request data to another service that won’t restart (we use ZeroMQ to stream request and logging data out of an ASP.NET app that I am writing….it is very performant).
Mike.