CloudTran Home

 
  
<< Back Contents  >  6.  The Low-Level API Forward >>

6.1 Overview: The Low-Level API for Cache Operations

This sections introduce the cache handling side of LLAPI.

 6.1.1  Cache Operations
 6.1.2  Additional Cache Features
 6.1.3  Restrictions

6.1.1  Cache Operations
LLAPI aims to minimise the number of changes you have to make to a Coherence application to make it transactional. In the JavaDocs, the LLAPI package is "com.cloudtran.coherence.llapi". Here is a quick overview of the supported features:
  1. You can start and commit transactions implicitly using Spring (via annotations or XML+AspectJ) or explicitly with program calls. e.g.
    @Transactional("transactionManager")
    public void transactionalMethodInsert()
    The @Transactional annotation is from Spring.

    When you call a transactional method like this, Spring starts the CloudTran transaction before the first line of the method is executed. The transaction is normally completed by returning from the method (for commit) or throwing an exception (to rollback).

  2. Alternatively, you can start and complete transactions programmmatically. To do this you need to get an instance of the CTx class from the CTxFactory class. There are a pair of start() methods in the CTx. For example
    CTx ctx = CTxFactory.get();
    ctx.start();
    starts a transaction with the default transactional settings. Alternatively, you can get the default transaction settings, change it, then use it to start the transaction:
    CTxDefinition ctxDefinition = new DefaultCTxDefinition();
    // change ctxDefinition
    ctx.start( ctxDefinition );
    In the examples below, we'll use 'ctx' to refer to a CTx instance.


    You use the 'ctx' object to complete the transaction:
    ctx.commit();
    ctx.rollback();
  3. You can then use caches non-transactionally using standard NamedCache objects, for example to retrieve committed data for lookups or reports. You can also use caches transactionally, for which you have to get a CTNamedCache. Again you get these from the CTx instance:
    CTNamedCache ctNamedCache = ctx.getCache( "testCache" );
    
  4. Now you can do the standard put/remove on cache entries:
    Object rv = ctNamedCache.put( "key", "value" ); // insert or update
    rv = ctNamedCache.remove( "key" );
  5. You can also use entry processors, which you invoke on a CloudTran-enhanced cache:
    public class TestEntryProcessor extends AbstractProcessor implements Serializable
    {
        public MyEntryProcessor()
        {
        }
        @Override
        public Object process( Entry entry )
        {
            entry.setValue( "999999" );  // probably only one of these
            entry.remove( true );
        }
        //////////////////////
        NamedCache ctNamedCache = ctx.getCache( "testCache" );
        ctNamedCache.invoke( "key", new MyEntryProcessor() );
    In this version, you cannot do updates to other entries (using partition-level transactions).
  6. Finally, you can use MapTriggers:
    public class TestMapTrigger implements MapTrigger
    {
        @Override
        public void process( Entry entry )
        {
            if( entry.getValue instanceof String )
            {
                String value = (String)entry.getValue;
                if( value.length > 15 )
                    entry.setValue( value.substring(0,15) ); // limit values to 15 characters, quietly
            }
        }

6.1.2  Additional Cache Features
You can do distributed transactions, but for now using a CloudTran-specific call to enrol (i.e. not using JTA or Spring framework).

To do this, you start a transaction as normal. Then you will have to retrieve the CTxDefinition transaction context, which you can do with getCurrentContext():
public void method1()
{
    ctxDefinition = ctx.getCurrentContext();
    // send to the other thread
}
Then you send the transaction context to another thread, possibly on another node. The other threads/nodes must "enrol" in the transaction, which will attach the transaction to the current thread. You can then use ctx.getCache() to get a transactional cache and use the features described earlier. Because the transaction was started manually, it must also be manually committed (CTx.commit()) or rolled back (CTx.rollback()).
public void enrollingMethod()
{
    CTxDefinition ctxDefinition;
    ...
    // receive ctxDefinition 
    ...
    ctx.enrol( ctxDefinition );
    NamedCache ctNamedCache = ctx.getCache( "testCache" );
    ctNamedCache.put( "key", "value" );
    ctx.commit();		// or ctx.rollback() 
}


6.1.3  Restrictions
The API does not currently support the following:
  1. Transactional Queries and Indexes. Queries will work on the committed values for now.
  2. JTA (i.e. with CloudTran acting as a resource manager). If you want to work with messaging, one solution is to use the Coherence grid as a transactional source or sink for messages.
  3. NamedCache.invokeAll() with filters.
  4. Extend clients.
  5. Partition-level transaction.

Copyright (c) 2008-2013 CloudTran Inc.