This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hi Guys, Please help me out here, i'm kinda desperate. Here's the thing: I have a counter on a certain row that has to be incremented each time an alarm is processed. Each alarm has it's own thread but because each thread has it's own unit of work, I am unable to synchronize the incrementation of that counter. I have tried using the same unit of work on all threads but failed as it is destroyed before other threads get to use it. (and you don't recomment doing this in your documentation) Say I have 100 threads trying to increment that counter, I only get 80 or 70 value of counter. The only way I could do this right was by manually writing the OracleCommand sql and executing it. @"UPDATE COUNTER_LOOKUP x This would not happen in NHibernate. How can I synchronize this row using lightspeed ? Thanks
|
|
|
Hi Bob, This sounds on the face of it more like a concurrency problem, in that you are losing values because there is an opportunity for multiple threads to be attempting to increment the counter at the same time causing a scenario where multiple threads might read in the counter value and then increment it to the same increment and save over the top of each other - does this sound correct for your scenario? If so, you could go down one of two routes - one would be to use a lock and read/write the counter value within the locked section, or alternatively mediate your counter writing through an external thread which lazily writes the updated counter value back to the database. The latter would work better in a high activity scenario where you want to reduce the amount of db access and its acceptable to be holding the counter in memory.
Jeremy |
|
|
Hi, Yes that is the correct scenario. I tried locking but it's not working because although the underlying row is the same, lightspeed creates different objects for it when in different units of work. Normally they should have been the same object returned. Because of this all threads can read at the same time, therefore many of them updating with the same value. Any chance this could change ? Will try your second suggestion. Thanks
|
|
|
Yes, each UnitOfWork is a new scope so it maintains its own identity map (L1 cache) of the object, so it sounds like mediating it centrally would reconcile better with what you are aiming for - let us know how you get on with this approach and if you run into any issues.
Jeremy |
|
|
Hi, I couldn't find any working solution other than manually calling an update sql sequence (with OracleConnection) to update that specific column like in my first post. Since the reading and the updating are done at the same time and are done by the DB, it doesen't matter from how many threads it's called. Handling it from a separate thread is not worth the effort since I shouldn't be doing this. It would have been nice if i could elegantly sinchronize this row between different UOW. I still think the correct way would be for lightspeed to return the same object for the same row, and it would be nice if this could be an option. Thanks |
|
|
Thanks for the update - we will have a think about this one; the UnitOfWork is a scope and the identity map is an internal part of that scope so as it currently stands we would not want to share that cache between threads, however it is possibly something which we could change and have as an option as to the scope of that cache (per UOW, per thread, per AppDomain..) which I believe would cover off what you are after. I will pop a ticket onto our backlog to look in to this.
Jeremy
|
|