Normalmente, as transações do eXtreme Scale começam com o método Session.begin e terminam com o método Session.commit. Entretanto, quando um ObjectGrid é integrado, um coordenador de transação externa pode iniciar e terminar transações. Nesse caso, você não precisa chamar os métodos begin ou commit.
O plug-in TransactionCallback é estendido com o método isExternalTransactionActive(Session session) que associa a sessão do eXtreme Scale com uma transação externa. O cabeçalho do método é o seguinte:
public synchronized boolean isExternalTransactionActive(Session session)
Por exemplo, o eXtreme Scale pode ser configurado para se integrar com o WebSphere Application Server e WebSphere Extended Deployment.
Além disso, o eXtreme Scale oferece um plug-in integrado chamado WebSphere Plug-ins para o Gerenciamento de Eventos de Ciclo de Vida da Transação, que descreve como construir o plug-in para ambientes do WebSphere Application Server, e também adaptar o plug-in para outras estruturas.
/**
* This method is required to associate an objectGrid session with a WebSphere
* Application Server transaction ID.
*/
Map/**/ localIdToSession;
public synchronized boolean isExternalTransactionActive(Session session)
{
// lembre-se de que este localid significa que a sessão é salva posteriormente.
localIdToSession.put(new Integer(jta.getLocalId()), session);
return true;
}
public J2EETransactionCallback() {
super();
localIdToSession = new HashMap();
String lookupName="java:comp/websphere/ExtendedJTATransaction";
try
{
InitialContext ic = new InitialContext();
jta = (ExtendedJTATransaction)ic.lookup(lookupName);
jta.registerSynchronizationCallback(this);
}
catch(NotSupportedException e)
{
throw new RuntimeException("Cannot register jta callback", e);
}
catch(NamingException e){
throw new RuntimeException("Cannot get transaction object");
}
}
Para outros produtos, é possível utilizar uma abordagem semelhante para recuperar o objeto de serviço de transações.
public class J2EETransactionCallback implements
com.ibm.websphere.objectgrid.plugins.TransactionCallback, SynchronizationCallback {
public J2EETransactionCallback() {
super();
String lookupName="java:comp/websphere/ExtendedJTATransaction";
localIdToSession = new HashMap();
try {
InitialContext ic = new InitialContext();
jta = (ExtendedJTATransaction)ic.lookup(lookupName);
jta.registerSynchronizationCallback(this);
} catch(NotSupportedException e) {
throw new RuntimeException("Cannot register jta callback", e);
}
catch(NamingException e){
throw new RuntimeException("Cannot get transaction object");
}
}
public synchronized void afterCompletion(int localId, byte[] arg1,boolean didCommit) {
Integer lid = new Integer(localId);
// find the Session for the localId
Session session = (Session)localIdToSession.get(lid);
if(session != null) {
try {
// if WebSphere Application Server is committed when
// hardening the transaction to backingMap.
// We already did a flush in beforeCompletion
if(didCommit) {
session.commit();
} else {
// otherwise rollback
session.rollback();
}
} catch(NoActiveTransactionException e) {
// impossible in theory
} catch(TransactionException e) {
// given that we already did a flush, this should not fail
} finally {
// always clear the session from the mapping map.
localIdToSession.remove(lid);
}
}
}
public synchronized void beforeCompletion(int localId, byte[] arg1) {
Session session = (Session)localIdToSession.get(new Integer(localId));
if(session != null) {
try {
session.flush();
} catch(TransactionException e) {
// WebSphere Application Server does not formally define
// a way to signal the
// transaction has failed so do this
throw new RuntimeException("Cache flush failed", e);
}
}
}
}
Session ogSession = ...;
ObjectMap myMap = ogSession.getMap("MyMap");
ogSession.begin();
MyObject v = myMap.get("key");
v.setAttribute("newValue");
myMap.update("key", v);
ogSession.commit();
public void myMethod() {
UserTransaction tx = ...;
tx.begin();
Session ogSession = ...;
ObjectMap myMap = ogSession.getMap("MyMap");
yObject v = myMap.get("key");
v.setAttribute("newValue");
myMap.update("key", v);
tx.commit();
}
O método myMethod é semelhante a um cenário de aplicativo da Web. O aplicativo usa a interface UserTransaction normal para iniciar, consolidar e recuperar transações. O eXtreme Scale automaticam ente inicia e consolida a transação do contêiner. Se o método for um método EJB (Enterprise JavaBeans) que usa o atributo TX_REQUIRES, então remova a referência UserTransaction e as chamadas para iniciar e consolidar transações e o método funciona da mesma forma. Neste caso, o contêiner é responsável por iniciar e encerrar a transação.