在我目前的项目中,缓存管理器需要根据事务提交状态对应用缓存进行管理。这里对其机制应用做一个小总结。
事务管理器
javax.transaction.TransactionManager接口定义一些方法以便应用服务器管理事务边界,比如获取与当前线程绑定的事务、对事务执行resume和suspend方法。
事务
javax.transaction.Transaction接口允许对目标事务对象执行相关的事务操作。在每个全局事务创建时,Transaction对象也对应的创建出来。 事务对象可以被用来做资源获取(resource enlistment)、同步器注册(synchronizationregistration)、事务结束(transaction completion)和状态查询(statusquery)操作。
事务同步机制
事务管理器通过javax.transaction.Synchronization接口支持一种同步机制。通过对当前事务的目标Transaction对象调用registerSynchronization方法,应用服务器为该事务注册一个Synchronization对象。 事务管理器在启动2PC事务提交过程时,回调Synchronization对象的beforeCompletion方法通知有关部分事务将要被提交;事务管理器在事务已经提交或回滚后,回调Synchronization对象的afterCompletion方法通知有关部分事务的结束状态。 应用一般很少使用beforeCompletion方法,afterCompletion方法使用比较多。在我目前的项目中,就是使用afterCompletion方法来通知缓存管理器对缓存进行更新操作。
实例代码
package com.yqu.transaction;
import java.lang.reflect.Method;
import javax.naming.InitialContext;
import javax.transaction.RollbackException;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
public class SynchronizationSample implements Synchronization {
private static int wepsphereVer;
private static final String WEBSPHERE_TM_FACTORY51 =
"com.ibm.ws.Transaction.TransactionManagerFactory";
private static final String WEBSPHERE_TM_FACTORY50 =
"com.ibm.ejs.jts.jta.TransactionManagerFactory";
private static final String WEBSPHERE_TM_FACTORY4 =
"com.ibm.ejs.jts.jta.JTSXA";
private static final String WEBLOGIC_TM_OBJNAME =
"javax.transaction.TransactionManager";
private static final String JBOSS_TM_OBJNAME =
"java:/TransactionManager";
private static final String TOMCAT_TM_OBJNAME =
"java:comp/env/TransactionManager";
private static final String WEBSPHERE_RECOG_CLASS =
"com.ibm.websphere.rsadapter.WSCallHelper";
private static final String WEBLOGIC_RECOG_CLASS =
"weblogic.transaction.Transaction";
private static final String JBOSS_RECOG_CLASS =
"org.jboss.Main";
public enum ServerType {
WEBSPHERE, WEBLOGIC, JBOSS, TOMCAT
}
public static ServerType getServerType() {
Class clazz;
try {
clazz = Class.forName(WEBSPHERE_RECOG_CLASS);
return ServerType.WEBSPHERE;
} catch (Throwable x1) {
try {
clazz = Class.forName(WEBLOGIC_RECOG_CLASS);
return ServerType.WEBLOGIC;
} catch (Throwable x2) {
try {
clazz = Class.forName(JBOSS_RECOG_CLASS);
return ServerType.JBOSS;
} catch (Throwable x3) {}
}
}
return ServerType.TOMCAT;
}
public static TransactionManager getTransactionManager() {
ServerType type = getServerType();
try {
if (type == ServerType.WEBSPHERE) {
Class clazz;
try {
clazz = Class.forName(WEBSPHERE_TM_FACTORY51);
wepsphereVer = 5; // 5.1
} catch (Exception e) {
try {
clazz = Class.forName(WEBSPHERE_TM_FACTORY50);
wepsphereVer = 5; // 5.0
} catch (Exception e2) {
clazz = Class.forName(WEBSPHERE_TM_FACTORY4);
wepsphereVer = 4;
}
}
Method method = clazz.getMethod("getTransactionManager",
(Class[]) null);
return (TransactionManager) method
.invoke(null, (Object[]) null);
} else {
String name = null;
if (type == ServerType.WEBLOGIC)
name = WEBLOGIC_TM_OBJNAME;
else if (type == ServerType.JBOSS)
name = JBOSS_TM_OBJNAME;
else
name = TOMCAT_TM_OBJNAME;
InitialContext ctx = new InitialContext();
return (TransactionManager) ctx.lookup(name);
}
} catch (Throwable x) {
x.printStackTrace();
}
return null;
}
public static Transaction getTransaction() throws IllegalStateException {
TransactionManager mgr = getTransactionManager();
try {
if (mgr == null) {
return null;
}
return mgr.getTransaction();
} catch (SystemException e) {
String msg = "can't get current transaction";
IllegalStateException x = new IllegalStateException(msg);
x.initCause(e);
throw x;
}
}
public void register() {
register(getTransaction());
}
public void register(Transaction transaction) {
if (transaction == null) {
return;
}
try {
transaction.registerSynchronization(this);
} catch (SystemException x) {
throw new RuntimeException(x);
} catch (RollbackException x) {
throw new RuntimeException(x);
} catch (IllegalStateException x) {
throw new RuntimeException(x);
}
}
@Override
public void beforeCompletion() {
}
@Override
public void afterCompletion(int status) {
// notify cache manager to update cache
}
public static void main(String[] args) {
// (new SynchronizationSample()).register();
}
}