I have created a copy-on-write cache concurrency strategy, where each session, after locking an entity, performs a copy on write into a local per session cache, and copies the write back into the main cache after an entity has been unlocked (assuming that the main cache item for this key is puttable).
This provides true repeatable read and read committed isolation for different sessions, and allows one session to access a cache key after another session locks it, as opposed to forcing the first session to hit the database. (Note: the copy on write cache only works for versioned entites).
The strategy uses a reader/writer lock for synchronizing access to the cache (ReaderWriterLockSlim), so performance should be good. (I've also converted the ReadWriteCache strategy in this patch to use a reader/writer lock)
The new strategy is called CowCache. Each session stores a local cache (HashtableCowCache), and items that are locked are put into this local cache. Subsequent updates are applied to this local cache. When the item is unlocked, it is written back to the main cache, if modified.
So, I have had to modify the ICache and ICacheConcurrencyStrategy interfaces to accept an ISessionImplementor in certain methods, in order to access the local, per session cache. I have also re-factored the cached item class.
I have added a test in the cache fixture, to test the basic functionality: storage, retrieval, and session isolation.
I have also successfully tested it on a production system at work.
Thanks!!
Aaron
Environment
None
Attachments
1
Activity
Aaron Boxer
December 9, 2010 at 12:56 PM
I made some improvements to the patch. This is the the one that should be reviewed.
New Cache Concurrency Strategy
I have created a copy-on-write cache concurrency strategy, where each session, after locking an entity, performs a copy on write into
a local per session cache, and copies the write back into the main
cache after an entity has been unlocked
(assuming that the main cache item for this key is puttable).
This provides true repeatable read and read committed isolation for
different sessions, and allows one session to access a cache key
after another session locks it, as opposed to forcing the first
session to hit the database. (Note: the copy
on write cache only works for versioned entites).
The strategy uses a reader/writer lock for synchronizing access to the
cache (ReaderWriterLockSlim), so performance should be
good. (I've also converted the ReadWriteCache strategy in this patch to use a
reader/writer lock)
The new strategy is called CowCache. Each session stores a local cache (HashtableCowCache), and items that are locked are put into this local cache.
Subsequent updates are applied to this local cache. When the item is unlocked,
it is written back to the main cache, if modified.
So, I have had to modify the ICache and ICacheConcurrencyStrategy interfaces to accept an ISessionImplementor in certain methods, in order to access the local, per session cache. I have also re-factored the cached item class.
I have added a test in the cache fixture, to test the basic functionality: storage, retrieval, and session isolation.
I have also successfully tested it on a production system at work.
Thanks!!
Aaron