beginner_
beginner_

Reputation: 7622

Cache for Java with transactions

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

Answers (3)

infinikli
infinikli

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

Victor Sorokin
Victor Sorokin

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

Mike Samuel
Mike Samuel

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

Related Questions