0
votes

My problem is that from time to time I end up with outdated objects in the cache due to one transaction evicting and before the transaction commits another transaction perform a read of the old value and thus also store it in the cache. This application is using spring and ehcache.

So far my research have come to these options, but I wouldn’t be surprised if there are more. Am I missing something?

Any advice is much appreciated :) What would you do and why.

Option 1: Ignoreance

Well, just ignore it and hope for the best. Not really an option.

Option 2: transactionAware=true

A property on the spring cache manager class. This removes one problem and introduces another. The evict is delayed until the transaction is committed and other transactions cannot intercept and store old data in the cache. Still, if I in the same transaction perform an operation that hits the cache I will get the old value since it hasn’t been evicted yet.

Option 3: XA

From the documentation it sounds like the recommended way.

Use this mode when you cache data from other data stores, such as a DBMS or JMS, and want to do it in an atomic way under the control of the JTA API ("Java Transaction API") but without the overhead of full two-phase commit.

Option 4: local transactions

Perhaps “cheaper” than XA but requires some manual work.

Option 5: redesign Change the design of the application so that these transactions don’t have race conditions.

1

1 Answers

0
votes

If you really want to be atomic, XA would be the way to go.

Then, Option 2 could be simpler but you would have to work in unit of work. The unit of work contains the valid data of the transaction. And prevent from fetching stale data from the cache. It is used as a cache over the cache. A example of that is the Hibernate session. Its content is always up-to-date for the transaction.