Developing eXtreme Scale client components to use transactions
The WebSphere® eXtreme Scale resource adapter provides client connection management and local transaction support. With this support, Java™ Platform, Enterprise Edition (Java EE) applications can look up eXtreme Scale client connections and demarcate local transactions with Java EE local transactions or the eXtreme Scale APIs.
Before you begin
About this task
You can optionally cast the javax.resource.cci.ConnectionFactory instance to a com.ibm.websphere.xs.ra.XSConnectionFactory that provides additional options for retrieving connection handles. The resulting connection handles must be cast to the com.ibm.websphere.xs.ra.XSConnection interface, which provides the getSession method. The getSession method returns a com.ibm.websphere.objectgrid.Session object handle that allows applications to use any of the eXtreme Scale data access APIs, such as the ObjectMap API and EntityManager API.
The Session handle and any derived objects are valid for the life of the XSConnection handle.
The following procedures can be used to demarcate eXtreme Scale transactions. You cannot mix each of the procedures. For example, you cannot mix global transaction demarcation and local transaction demarcation in the same application component context.
Procedure
Example
// (C) Copyright IBM Corp. 2001, 2012.
// All Rights Reserved. Licensed Materials - Property of IBM.
package com.ibm.ws.xs.ra.test.ee;
import javax.naming.InitialContext;
import javax.resource.cci.Connection;
import javax.resource.cci.ConnectionFactory;
import javax.resource.cci.LocalTransaction;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import junit.framework.TestCase;
import com.ibm.websphere.objectgrid.ObjectMap;
import com.ibm.websphere.objectgrid.Session;
import com.ibm.websphere.xs.ra.XSConnection;
/**
* This sample requires that it runs in a J2EE context in your
* application server. For example, using the JUnitEE framework servlet.
*
* The code in these test methods would typically reside in your own servlet,
* EJB, or other web component.
*
* The sample depends on a configured WebSphere eXtreme Scale connection
* factory registered at of JNDI Name of "eis/embedded/wxscf" that defines
* a connection to a grid containing a Map with the name "Map1".
*
* The sample does a direct lookup of the JNDI name and does not require
* resource injection.
*/
public class DocSampleTests extends TestCase {
public final static String CF_JNDI_NAME = "eis/embedded/wxscf";
public final static String MAP_NAME = "Map1";
Long key = null;
Long value = null;
InitialContext ctx = null;
ConnectionFactory cf = null;
public DocSampleTests() {
}
public DocSampleTests(String name) {
super(name);
}
protected void setUp() throws Exception {
ctx = new InitialContext();
cf = (ConnectionFactory)ctx.lookup(CF_JNDI_NAME);
key = System.nanoTime();
value = System.nanoTime();
}
/**
* This example runs when not in the context of a global transaction
* and uses autocommit.
*/
public void testLocalAutocommit() throws Exception {
Connection conn = cf.getConnection();
try {
Session session = ((XSConnection)conn).getSession();
ObjectMap map = session.getMap(MAP_NAME);
map.insert(key, value); // Or various data access operations
}
finally {
conn.close();
}
}
/**
* This example runs when not in the context of a global transaction
* and demarcates the transaction using session.begin()/session.commit()
*/
public void testLocalSessionTransaction() throws Exception {
Session session = null;
Connection conn = cf.getConnection();
try {
session = ((XSConnection)conn).getSession();
session.begin();
ObjectMap map = session.getMap(MAP_NAME);
map.insert(key, value); // Or various data access operations
session.commit();
}
finally {
if (session != null && session.isTransactionActive()) {
try { session.rollback(); }
catch (Exception e) { e.printStackTrace(); }
}
conn.close();
}
}
/**
* This example uses the LocalTransaction interface to demarcate
* transactions.
*/
public void testLocalTranTransaction() throws Exception {
LocalTransaction tx = null;
Connection conn = cf.getConnection();
try {
tx = conn.getLocalTransaction();
tx.begin();
Session session = ((XSConnection)conn).getSession();
ObjectMap map = session.getMap(MAP_NAME);
map.insert(key, value); // Or various data access operations
tx.commit(); tx = null;
}
finally {
if (tx != null) {
try { tx.rollback(); }
catch (Exception e) { e.printStackTrace(); }
}
conn.close();
}
}
/**
* This example depends on an externally managed transaction,
* the externally managed transaction might typically be present in
* an EJB with its transaction attributes set to REQUIRED or REQUIRES_NEW.
* NOTE: If there is NO global transaction active, this example runs in auto-commit
* mode because it doesn't verify a transaction exists.
*/
public void testGlobalTransactionContainerManaged() throws Exception {
Connection conn = cf.getConnection();
try {
Session session = ((XSConnection)conn).getSession();
ObjectMap map = session.getMap(MAP_NAME);
map.insert(key, value); // Or various data access operations
}
catch (Throwable t) {
t.printStackTrace();
UserTransaction tx = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
if (tx.getStatus() != Status.STATUS_NO_TRANSACTION) {
tx.setRollbackOnly();
}
}
finally {
conn.close();
}
}
/**
* This example demonstrates starting a new global transaction using the
* UserTransaction interface. Typically the container starts the global
* transaction (for example in an EJB with a transaction attribute of
* REQUIRES_NEW), but this sample will also start the global transaction
* using the UserTransaction API if it is not currently active.
*/
public void testGlobalTransactionTestManaged() throws Exception {
boolean started = false;
UserTransaction tx = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
if (tx.getStatus() == Status.STATUS_NO_TRANSACTION) {
tx.begin();
started = true;
}
// else { called with an externally/container managed transaction }
Connection conn = null;
try {
conn = cf.getConnection(); // Get connection after the global tran starts
Session session = ((XSConnection)conn).getSession();
ObjectMap map = session.getMap(MAP_NAME);
map.insert(key, value); // Or various data access operations
if (started) {
tx.commit(); started = false; tx = null;
}
}
finally {
if (started) {
try { tx.rollback(); }
catch (Exception e) { e.printStackTrace(); }
}
if (conn != null) { conn.close(); }
}
}
/**
/**
* This example demonstrates a multi-partition transaction.
*/
public void testGlobalTransactionTestManagedMultiPartition() throws Exception {
boolean started = false;
XSConnectionSpec connSpec = new XSConnectionSpec();
connSpec.setWriteToMultiplePartitions(true);
UserTransaction tx = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
if (tx.getStatus() == Status.STATUS_NO_TRANSACTION) {
tx.begin();
started = true;
}
// else { called with an externally/container managed transaction }
Connection conn = null;
try {
conn = cf.getConnection(connSpec); // Get connection after the global tran starts
Session session = ((XSConnection)conn).getSession();
ObjectMap map = session.getMap(MAP_NAME);
map.insert(key, value); // Or various data access operations
if (started) {
tx.commit(); started = false; tx = null;
}
}
finally {
if (started) {
try { tx.rollback(); }
catch (Exception e) { e.printStackTrace(); }
}
if (conn != null) { conn.close(); }
}
}