0

I am trying to use Infinispan as Hibernate L2 cache for an application which use technologies like Tomcat 6, Hibernate 4 and Spring 3.5. The application running in Tomcat and our current transaction manager is

    org.springframework.orm.hibernate4.HibernateTransactionManager

We have introduced following properties to hibernate property file for Infinispan introduction.

hibernate.cache.region.factory_class=org.hibernate.cache.infinispan.InfinispanRegionFactory
hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory 
   hibernate.transaction.jta.platform=org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform 
   hibernate.transaction.manager_lookup_class=org.hibernate.cache.infinispan.tm.HibernateTransactionManagerLookup

After the introduction of Infinispan we lost the stability of the application and start to get different errors randomly. I assume our Infinispan configurations are not correct (we use a transnational cache). I think our transaction manager and Infinispan transaction settings not match. Please advice for correct configuration.

Errors we see

    java.lang.IllegalStateException: Transaction TransactionImple < ac, BasicAction: 0:ffff0a1e015a:c2f8:51921dac:3de status: ActionStatus.ABORTED > is not in a valid state to be invoking cache operations on.

    org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction

Infinispan configuration file I use

    <?xml version="1.0" encoding="UTF-8"?>
    <infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:infinispan:config:5.1"
                xsi:schemaLocation="urn:infinispan:config:5.1 http://www.infinispan.org/schemas/infinispan-config-5.1.xsd">

        <global>
            <globalJmxStatistics enabled="true" jmxDomain="org.infinispan" allowDuplicateDomains="true"/>
            <transport
                    transportClass="org.infinispan.remoting.transport.jgroups.JGroupsTransport"
                    clusterName="infinispan-hibernate-cluster"
                    distributedSyncTimeout="50000"
                    strictPeerToPeer="false">
                <properties>
                    <property name="configurationFile" value="jgroups.xml"/>
                </properties>
            </transport>
        </global>

        <default>
        </default>

        <namedCache name="aaa-replicated-cache-entity">
            <clustering mode="replication">
                <stateRetrieval fetchInMemoryState="false" timeout="60000"/>
                <sync replTimeout="20000"/>
            </clustering>
            <locking isolationLevel="READ_COMMITTED" concurrencyLevel="1000"
                     lockAcquisitionTimeout="15000" useLockStriping="false"/>
            <eviction maxEntries="10000" strategy="LRU"/>
            <expiration maxIdle="100000" wakeUpInterval="5000"/>
            <lazyDeserialization enabled="true"/>
            <transaction useSynchronization="true"                      
                         transactionMode="TRANSACTIONAL" autoCommit="false"
                         lockingMode="OPTIMISTIC"/>
            <loaders passivation="false" shared="false" preload="false">
                <loader class="org.infinispan.loaders.cluster.ClusterCacheLoader"
                        fetchPersistentState="false"
                        ignoreModifications="false" purgeOnStartup="false">
                    <properties>
                        <property name="remoteCallTimeout" value="20000"/>
                    </properties>
                </loader>
            </loaders>
        </namedCache>
    </infinispan>


    Thanks
artless noise
  • 21,212
  • 6
  • 68
  • 105
era
  • 391
  • 4
  • 24
  • Any Infinispan configuration that you use must be based on https://github.com/hibernate/hibernate-orm/blob/master/hibernate-infinispan/src/main/resources/org/hibernate/cache/infinispan/builder/infinispan-configs.xml and then modify that accordinly - The rest of caches are there for a reason :) – Galder Zamarreño May 16 '13 at 09:36
  • Thanks Galder. What you see wrong in my configuration ? I am not using query cache and so entries relate to query cache not in the infinispan configuration file. – era May 17 '13 at 12:03
  • Well, I can't see if you have some region overrides to name the region for your cache to aaa-replicated-cache-entity via annotation or xml... otherwise, that cache should be called "entity". If you're having issues, go to the default configuration and at least you have one less thing to worry about. Most likely here though, as you already say, the issue is with the transaction manager and integration. You should check the logs to see what's caused the transaction to be aborted... – Galder Zamarreño May 21 '13 at 07:05
  • Thanks. By further looking I identified my app using a JDBC transaction manager through a Spring. I can not find any sample configuration for a such setup. I have JDBC trx manager with Spring / Hibernate. I am doubt what will be the matching Infinispan transaction.manager_lookup_class, transaction.factory_class ...etc – era May 22 '13 at 12:53
  • I have a few standalone examples in https://github.com/galderz/secondlc - All the config you need for a standalone application with Spring and Hibernte should be region factory and JTA plattform. The rest is not needed. You do of course need a JTA transaction manager. See http://goo.gl/sDfMB and http://goo.gl/2krUo – Galder Zamarreño May 23 '13 at 13:01
  • Thanks. As per my understanding when L2 cache is transnational then need a JTA in place. I can not go to JTA due to overhead of JTA. Even to use hibernate4 synchronization resources need to be a XA/JTA. I wonder why simple JDBC based approach is not there for transnational L2. If cache commit fails then can avoid DB commit. We can not expect to fail the DB commit. I'll ask that question in a separate thread. I made the cache none transnational. Then seems everything fine. But I do not know how long I'll be in good shape. – era May 27 '13 at 13:13
  • Right, fot JDBC transactions you use cache modes read-write and read-write-strict, which Infinispan does not yet support, but we're looking to add them. But, JDBC transactions is tricky when doing a cluster because you need to coordinate with other nodes, and that's where JTA offers better capabilities for this coordination with other nodes. JDBC transactions are single node really, they're not designed to be distributed with other clustered nodes. – Galder Zamarreño May 28 '13 at 08:47
  • OMG. I thought Infinispan JTA usage to commit two resources (cache and the DB) in a single node. Then cache itself replicated the change to the other cluster nodes. Is it not ? Does global transaction wait until all the caches updated in a cluster? – era May 29 '13 at 10:39
  • With JTA, first of all Infinispan is able to participate in the on-going Hibernate JTA transaction. Secondly, the transaction is used to verify the contents have been replicated/invalidated correctly in other nodes and commit/rollback accordingly. For the entity cache, communications are synchronous, so it waits for other nodes to update their caches. – Galder Zamarreño May 30 '13 at 07:48
  • thanks Galder for the clarification. I am doubt about the performance gain I can get if I move to JTA with all these cluster locks, 2PC ...etc. So I think best option for me is JDBC or some other light weight approach. Are there any plan for that ? Does it make sense to use "distribution" transport for L2 cache ? – era Jun 03 '13 at 06:58

0 Answers0