Results 1 to 7 of 7

Thread: ACL: Cleanup aclCache after Transaction Rollback/Exception

  1. #1
    Join Date
    Dec 2009
    Posts
    3

    Talking ACL: Cleanup aclCache after Transaction Rollback/Exception

    Hi all (:

    I encountered a problem using Spring 3.0.7 / Spring Security 3.1.0.RC3 and hope you guys can help me out or at least point me to the right direction.

    The scenario is as follows:

    When a expection is thrown inside my transactional, the transaction (using JTA - Atomikos Transactionmanager) gets rolled back correctly on the database, but the ACL Mutations made are still in the aclCache (I'm using EhCache).

    I found a workaround, but imo it's pretty ugly :

    I looked into the source. The desired behaviour is obviously inside of JdbcMutableAclService' private method 'clearCacheIncludingChildren(ObjectIdentity objectIdentity)'

    Code:
      
    private void clearCacheIncludingChildren(ObjectIdentity objectIdentity) 
    {
            Assert.notNull(objectIdentity, "ObjectIdentity required");
            List<ObjectIdentity> children = findChildren(objectIdentity);
            if (children != null) {
                for (ObjectIdentity child : children) {
                    clearCacheIncludingChildren(child);
                }
            }
            aclCache.evictFromCache(objectIdentity);
       }
    This function is usually called aftern ACL Update.
    Since neither this method nor the aclCache is accessible from another class, I extended JdbcMutableAclService and added a reference to aclCache, a public cleanUp Method (see below) and copy of the above method.
    Code:
    public MutableAcl cleanupAcl( ObjectIdentityImpl oi)
    {
    	clearCacheIncludingChildren( oi);
    	return (MutableAcl) super.readAclById(oi);
    }
    When I throw an Exception the the corresponding ObjectIdentity is passed. The catch block looks like this
    Code:
     
       try {
          //doSomething is a Transactional Service Method where the object is updated and the acl update/insert is  made
          doSomething();
       catch (CustomException e) {	
    		MutableAcl acl = customJdbcMutableAcleService.cleanupAcl( e.getObjectIdentity());
       }

    I assume (or lets say I hope ) there is another easy way to notify the EHCache after a transaction is rolled back.

    thanks in advance... appreciate it.
    Last edited by ko0kie; Jan 19th, 2012 at 06:04 PM.

  2. #2
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    I'm not sure if you have taken a look, but ehcache has some documentation on transaction management that may help.

    PS: You might consider updating to Spring Security 3.1.0.RELEASE
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  3. #3
    Join Date
    Dec 2009
    Posts
    3

    Default

    thanks for your advice. I upgraded to Spring Security / Spring 3.1.0.RELEASE.

    I also had a good look at the ehcache documentation, updated my configuration but still did'nt get it to work.

    my configuration:

    applicationContext-acl.xml:
    Code:
    <bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
            <constructor-arg>
                <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
                    <property name="cacheManager">
                        <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
                        	<property name="configLocation" value="/WEB-INF/ehcache.xml"/>
                        </bean>
                    </property>
                    <property name="cacheName" value="aclCache"/>
                </bean>
            </constructor-arg>
        </bean>
    ehcache.xml
    Code:
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" name="myCache">
    	<diskStore path="java.io.tmpdir"/>
    	<defaultCache
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="240"
           overflowToDisk="true"
           maxEntriesLocalDisk="1000000"
           diskPersistent="false"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU"
           transactionalMode="xa"/>
    </ehcache>
    I also tried transactionalMode="xa_strict"..same result.

  4. #4
    Join Date
    Oct 2011
    Posts
    4

    Default

    Hi ko0kie!

    I've got the same problem and I also tried the transactionalMode in the ehcache configuration ... but nothing orking.
    Did you finally find a solution to clean ehCache after rollback?

    Thx a lot

  5. #5
    Join Date
    Mar 2005
    Location
    Tokyo, Japan
    Posts
    103

    Default

    I'm having the same problem here.
    ehcache transactionalMode doesn't seem to do what we expect.

    ko0kie, have you stick with your work around or have you manage to get this working?

  6. #6
    Join Date
    May 2012
    Posts
    3

    Default

    There are two aspects:

    In order to activate transactionalMode for the aclCache you have to explictly define it in your ehcache.xml. It isn't enough to set it for the defaultCache.
    So your ehcache.xml should look like this:

    Code:
    <ehcache  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    	<diskStore path="java.io.tmpdir"/>
    	<defaultCache
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           maxEntriesLocalDisk="1000000"
           diskPersistent="false"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU"/>
           
       <cache name="aclCache"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           maxEntriesLocalDisk="2000000"
           diskPersistent="false"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU"
          transactionalMode="xa"
           />
    </ehcache>
    As soon as you activate transactionalMode for your aclCache Spring will most probably complain that a TransactionManager wasn't found. According to the documentation of ehcache you have to define a custom TransactionManagerLookup if your transactionManager is not part of the ones which are supported out of the box.
    However the TransactionManagerLookup requires to return a JtaTransactionManager. So in case you are using a JpaTransactionManager it will again complain.

    I don't know if there is an easier workaround.

  7. #7
    Join Date
    Oct 2012
    Posts
    1

    Default

    you could pass the aclCache to the class that takes care of adding the entries to the ACL database

    class AclUtil {
    private MutableAclService mutableAclService;
    private AclCache aclCache;

    public void evict(ObjectIdentity oid){
    aclCache.evictFromCache(oid);
    }

    public void addPermissions( ObjectIdentity oid, .. ){
    MutableAcl acl;
    try {
    acl = (MutableAcl) mutableAclService.readAclById(oid);
    } catch (NotFoundException nfe) {
    acl = mutableAclService.createAcl(oid);
    }
    ....
    mutableAclService.updateAcl(acl);
    }
    }


    and what ever calls the addPermissions()...
    try {
    aclUtil.addPermissions( oid, ... );
    } catch ( TheException e ) {
    aclUtil.evict(oid);
    }

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •