The classic trade off is that you are probably trying
to implement a fine grained locking mechanism, and a lock hierarchy
invariably pushes the design back to doing more coarse grained
locking, so it's a very delicate balance to find. It's usually best to
start with a simple coarse grained locking mechanism, then measure
performance and move to a more complicated solution only if necessity
requires it.
So true Scott. You can get bound up in a nest of locks and your
thread-lock-bug matrix expands like my stomach at Thanksgiving. I went down
the fine grain lock for a memory based object db thing I was doing and went
back and forth a couple times. In the end, I found one lock was better then
anything else I could come up with. Especially, when you concider other
"Users" for your DB like WebServices, etc. Some API may want to iterate
over your collection(s), some update, and some read. Also remember that RW
locks are a lot slower then monitors, so you need to factor in the
cost/benefits of that. You may be able to service 3+ Monitor requests for
every one (need to test) RW lock and add multiple RW or monitor locks and
things get a bit slower still. Also, the more locks you need to
grab...well, the more locks you need to grab - and they are not free. So
fewer towards one "may" be better depending. Also, you may want to look at
a larger thread picture. How many threads do you actually need? Are you
sure you need that many? Is it making your app more responsive (i.e. more
requests per second) or slower? How much blocking is going on inside the
APIs? Maybe only one thread needs to touch the db at any one time and all
requests are serviced from a blocking circular queue so no lock may even be
required (cq will still need one lock) - this method has a lot to love about
it - but depends on your design and needs. Interesting and complex topic.
Cheers.