TopLink源代码分析 JTA的部分技术实现细节
[什么是JTA]
Java事务API(JTA;Java Transaction API)和它的同胞Java事务服务(JTS;Java TransactionService),为J2EE平台提供了分布式事务服务。一个分布式事务(distributedtransaction)包括一个事务管理器(transaction manager)和一个或多个资源管理器(resource manager)。一个资源管理器(resource manager)是任意类型的持久化数据存储。事务管理器(transaction manager)承担着所有事务参与单元者的相互通讯的责任。下图显示了事务管理器和资源管理的间的关系。
JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中:
.JDBC连接
.JDO PersistenceManager 对象
.JMS 队列
.JMS 主题
.企业JavaBeans(EJB)
.一个用J2EE Connector Architecture 规范编译的资源分配器。
简单的说,JTA实现了在分布式系统中对单一事务的提交和管理。
[源代码分析]
第一步:当连接数据库的时候,前期的准备函数,这里面都发生了什么?
/** * INTERNAL: * This method includes all of the code that is issued before the datasource * is connected to. */ protected void preConnectDatasource(){ //Bug#3440544 Check if logged in already to stop the attempt to login more than once if (isLoggedIn) { throw ValidationException.alreadyLoggedIn(this.getName()); } this.platform = null; if (isInProfile()) { getProfiler().initialize(); } updateProfile(SessionProfiler.LoginTime, new Date(System.currentTimeMillis()));
// Login and initialize getEventManager().preLogin(this); //setup the external transaction controller getServerPlatform().initializeExternalTransactionController(); log(SessionLog.INFO, null, "topLink_version", DatasourceLogin.getVersion()); if (getServerPlatform().getServerNameAndVersion() != null) { log(SessionLog.FINE, null, "application_server_name_and_version", getServerPlatform().getServerNameAndVersion()); } } |
第二步:上面的程序中,有这样一行代码
//setup the external transaction controller getServerPlatform().initializeExternalTransactionController();
它是干什么的呢???
public void initializeExternalTransactionController() { this.ensureNotLoggedIn();
//BUG 3975114: Even if JTA is disabled, override if we're in CMP //JTA must never be disable during CMP (WLS/Oc4j) if (!isJTAEnabled() && !isCMP()) { return; } //BUG 3975114: display a warning if JTA is disabled and we're in CMP if (!isJTAEnabled() && isCMP()) { AbstractSessionLog.getLog().warning("jta_cannot_be_disabled_in_cmp"); } //check if the transaction controller class is overridden by a preLogin or equivalent, //or if the transaction controller was already defined, in which case they should have written //a subclass. Show a warning try { if (getDatabaseSession().getExternalTransactionController() != null) { this.externalTransactionControllerNotNullWarning(); return; } ExternalTransactionController controller = null; if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ try { controller = (ExternalTransactionController)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(this.getExternalTransactionControllerClass())); } catch (PrivilegedActionException exception) { Exception throwableException = exception.getException(); if (throwableException instanceof InstantiationException) { throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName()); } else { throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName()); } } } else { controller = (ExternalTransactionController)PrivilegedAccessHelper.newInstanceFromClass(this.getExternalTransactionControllerClass()); } getDatabaseSession().setExternalTransactionController(controller); } catch (InstantiationException instantiationException) { throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName()); } catch (IllegalAccessException illegalAccessException) { throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName()); } } |
乖乖~~~~~这么长的函数,鬼知道它做的是什么。。。。
不过,貌似它里面有这样一行话。
getDatabaseSession().setExternalTransactionController(controller);
乖乖~~~~原来是用来启动JTA事务管理控制器的。。。快点去看看它干了什么。。
第三步:啊哈,奥秘在这里
public class SunAS9TransactionController extends JTATransactionController { // Use "java:appserver/TransactionManager" instead of java:pm/TransactionManager // as the former one is available in ACC as well as server. // See com.sun.enterprise.naming.java.javaURLContext in GlassFish appserv-core public static final String JNDI_TRANSACTION_MANAGER_NAME = "java:appserver/TransactionManager";
public SunAS9TransactionController() { super(); }
/** * INTERNAL: * Obtain and return the JTA TransactionManager on this platform */ protected TransactionManager acquireTransactionManager() throws Exception { return (TransactionManager)jndiLookup(JNDI_TRANSACTION_MANAGER_NAME); } } |
同志们看见了吗~~~~
public static final String JNDI_TRANSACTION_MANAGER_NAME = "java:appserver/TransactionManager"; |
搞了半天,原来它用JMX启动了一个交易服务来管理JTA~~~
???什么是JMX~~~~~
请看下回分解。。。