在我目前的项目中,缓存管理器需要根据事务提交状态对应用缓存进行管理。这里对其机制应用做一个小总结。
事务管理器
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();
  }
}