Transactions with Spring Cache Abstraction and JDBC DAO

caching, java, locking, spring, transactions

Solution

I should've looked into EHCache documentation a bit more because the answer is here.

EHCache 2.4+ works with Spring's @Transactional annotation. Just need to configure a transaction manager lookup.

Problem

I'm testing out Spring's `@Cacheable` features with EHCache but I can't find anything on whether this works with Spring's `@Transactional` annotations. I am placing `@Cacheable` and `@CacheEvict` on DAO methods while `@Transactional` are on service methods. Suppose my User DAO looks like this: ``` @Cacheable(value="users", key="#id") User find(BigInteger id); @CacheEvict(value="users", key="#user.id") void update(User user); @CacheEvict(value="users", key="#id") void delete(BigInteger id); ``` A problem may arise when, for example, getUser() is called while removeFriend() is in progress, because the user with the stale friend count would be re-cached (or would it?): ``` public User getUser(userId) { return userDao.find(userId); } @Transactional public void removeFriend(userId, friendId) { friendDao.remove(friendId); user.setFriendCount(--numFriends); userDao.update(user); // do some other stuff } ``` How can I ensure that this doesn't update the cache before the database transaction has completed? Do I place `@CacheEvict` on service methods in addition to the DAO methods? Or, do I add read/write locking to the service methods? And if so to locking, are there any libraries to lock based on id since I would only want to lock on each user instead of locking globally, e.g. `@GuardedBy("userLocks.getReadLock(#userId)")`? Is there a generally accepted way of handling caching and transactions? Many thanks!

Original source