i would like to have a simple cache that supports transactions. With simple I mean that I just want to load all data at startup and no eviction or so is needed. (simple Map would do).
However it should support transactions as that if a change to the database fails, changes made to the cache get rolled back too.
I’ve heard about JTA but it seems too much for what I need. It would be fine to manually roll back the cache if SQLException is thrown in database transaction.
Are there any options?
If not can someone point me to a good tutorial about JTA? eg. examples and what packages/classes required. Note: I’m creating a framework so it must be able to run standalone without application container.
EDIT:
Forgot 1 very important issue:
Cached objects are immutable! Update means to replace it with a new object that is equal to old one (id based equals method).
EDIT 2:
Wrote JPA instead of JTA…
EDIT 3:
Explanation why simple Map does not work:
I have 2 entity types. I will call them Compound and Element. A compound can consist of multiple elements and each element can appear in multiple compounds.
Elements are managed by my framework. Eg, only compounds can be added directly. The user adds a new compound by specifying its elements. The framework then either selects and exiting element and associates it with the new Compound or create a new Element.
I’m caching all the elements where each element contains a collection of Compound IDs in which the element occurs. Reason for this is that the framework does a special kind of search (eg subgraph isomorphism). For each such search, the whole!!! dataset (all elements) needs to be loaded from database, hence the cache.
Therefore if a new Compound was added or updated, the affected elements in the cache must be updated too.
Solution:
Did what I said in comments:
– keep ids (=integers) of all changed objects in memory and then only update the changed ones after database transaction commits.
private void updateSearchCache(Collection<String> changedIds,
Connection connection) {
synchronized (searchCache) {
for (String id : changedIds) {
Object myObject = getSearchObject(id, connection);
searchCache.put(id, myObject);
}
}
}
Can’t you just put your data into a
Mapafter transaction is committed to database, can you?So, your
Mapwill contain only the data which is already in database.