8 Replies Latest reply on Jan 18, 2017 8:50 AM by vladsz83

    Transaction question with multiple cache.

    seto

      Is the transaction related to a specific cache?

      I try the code below.

      getIdCache().getAdvancedCache().getTransactionManager().begin();
      getKeyCache().getAdvancedCache().getTransactionManager().begin();
      

      But I get the exception below.

      Thread[pool-6-thread-1,5,main] is already associated with a transaction (DummyTransaction{xid=DummyXid{id=1}, status=0})

        • 1. Re: Transaction question with multiple cache.
          vladsz83

          Probably because transaction is bound to the calling thread. I guess the caches share the same transaction manager, so it can’t open transaction twice.

          • 2. Re: Transaction question with multiple cache.
            seto

            Vlad St wrote:

             

            Probably because transaction is bound to the calling thread. I guess the caches share the same transaction manager, so it can’t open transaction twice.

            Does it actually share transaction?

            What if with requirements that treat multiple caches separately?

            • 3. Re: Transaction question with multiple cache.
              rvansa

              Yes, these are JTA transactions bound to current thread, so they're shared between caches and possibly another resources that register to it (e.g. DB connection, JMS...).

               

              You can temporarily suspend a transaction using TransactionManager.suspend(), start another one and later resume it using TransactionManager.resume().

              • 4. Re: Transaction question with multiple cache.
                seto

                Radim Vansa wrote:

                 

                Yes, these are JTA transactions bound to current thread, so they're shared between caches and possibly another resources that register to it (e.g. DB connection, JMS...).

                 

                You can temporarily suspend a transaction using TransactionManager.suspend(), start another one and later resume it using TransactionManager.resume().

                Thank you for your clarifying. For now I can use one begin and one commit or one rollback. But I may have requirements for separate transaction in the future.

                 

                But if I want to do stuffs this. Maybe a and b fail and rollback. But keep the c and d. Then it's not an easy way to suspend and resume.

                acache.transaction.start

                bcache.transaction.start

                ccache.transaction.start

                dcache.transaction.start

                 

                try{

                // do something with a b c d cache

                // which is wrote by users of my library

                 

                acache.transaction.commit

                bcache.transaction.commit

                }catch(e)

                {

                acache.transaction.rollback

                bcache.transaction.rollback

                }

                 

                try{

                // I do something myself

                ccache.transaction.commit

                dcache.transaction.commit

                }catch(e)

                {

                ccache.transaction.rollback

                dcache.transaction.rollback

                }

                • 5. Re: Transaction question with multiple cache.
                  seto

                  And also, can anyone tell me how to use JBossStandaloneJTAManagerLookup programmatically? I can use dummy only.

                  When I use the code below, it will report execption below.

                  builder.transaction().transactionManagerLookup(new JBossStandaloneJTAManagerLookup());
                  

                  Exception in thread "main" org.infinispan.commons.CacheException: This is transactional cache but no transaction manager could be found. Configure the transaction manager lookup properly.

                  • 6. Re: Transaction question with multiple cache.
                    rvansa

                    You want users of your library to participate on two independent transactions, and determining which transaction should given operation be applied to according to the cache? I guess that in that case you have to create a wrapper for the exposed API (e.g. Cache if you're exposing that directly) that will automatically choose which transaction should it resume.

                     

                     

                    There's no easier way because this is not a common usecase, e.g. using CMT,  all operations within a container-invoked method belong to single transaction. In the example, what's your reason to deal with independent transactions for cache A and B, instead of using single transaction to wrap whole user operation?

                     

                    Also note that your approach does not give you ACIDity - if dcache.transaction fails to commit, rolling back ccache.transaction has no effect, since it has been already comitted. Also you're losing some possibilities to optimize the transaction.

                    • 7. Re: Transaction question with multiple cache.
                      seto

                      Thank you. I'm wrapping the API. I can know which to choose. For now, I'll use a share transaction for now.

                       

                      And also JBossStandaloneJTAManagerLookup working now after I add the following dependencies.

                       

                      compile "org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec"
                      compile "org.jboss:jboss-transaction-spi:${jboss_transaction_spiVersion}"
                      compile "org.jboss.narayana.jta:narayana-jta:${narayanaVersion}"

                      • 8. Re: Transaction question with multiple cache.
                        vladsz83

                        Try something like this:

                         

                        EmbeddedCacheManager manager = new DefaultCacheManager(...);

                         

                        JBossStandaloneJTAManagerLookup jBossStandaloneJTAManagerLookup = new JBossStandaloneJTAManagerLookup();

                        jBossStandaloneJTAManagerLookup.init(manager.getCacheManagerConfiguration());

                        transactionManagerLookup = jBossStandaloneJTAManagerLookup;

                         

                        manager.getDefaultCacheConfiguration().transaction()

                          .transactionManagerLookup(transactionManagerLookup);