title: Cache for Java with transactions
body: <p>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).</p>
  
  <p>However it should support transactions as that if a change to the database fails, changes made to the cache get rolled back too.</p>
  
  <p>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.</p>
  
  <p>Are there any options?</p>
  
  <p>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.</p>
  
  <p>EDIT:</p>
  
  <p>Forgot 1 very important issue:</p>
  
  <p>Cached objects are immutable! Update means to replace it with a new object that is equal to old one (id based equals method).</p>
  
  <p>EDIT 2:</p>
  
  <p>Wrote JPA instead of JTA...</p>
  
  <p>EDIT 3:</p>
  
  <p>Explanation why simple Map does not work:</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>Therefore if a new Compound was added or updated, the affected elements in the cache must be updated too.</p>
  
  <p>Solution:</p>
  
  <p>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.</p>
  
  <pre><code>private void updateSearchCache(Collection&lt;String&gt; changedIds,
          Connection connection) {
  
      synchronized (searchCache) { 
          for (String id : changedIds) {
              Object myObject = getSearchObject(id, connection);
              searchCache.put(id, myObject);
          }
      }
  }
  </code></pre>