Reputation: 7622
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);
}
}
}
Upvotes: 3
Views: 3336
Reputation: 73
Transactional caching is possible with infinispan. Although it is designed as a clustered cache it can be easily run on one machine. The cache-api extends java.util.Map and is easy to use.
Upvotes: 0
Reputation: 11996
Can't you just put your data into a Map
after transaction is committed to database, can you?
So, your Map
will contain only the data which is already in database.
Upvotes: 2
Reputation: 120506
Berkeley DB can be used to create in-memory tables and has transactional support.
It's a fine choice, if what you want to store are blob->blob mappings, but it is not an object cache.
Upvotes: 0