(1). 概述
前面分析到:TransactionalTemplate会把请求委派给:GlobalTransaction处理. 在这里我将分析:DefaultGlobalTransaction,因为它是:GlobalTransaction的实现类.
(2). GlobalTransaction类详解
我在这里只剖析:TransactionalTemplate用到的三个方法(begin/commit/rollback).
(3). 先看一下DefaultGlobalTransaction的构造器和相关的属性
private static final int DEFAULT_GLOBAL_TX_TIMEOUT = 60000;
private static final String DEFAULT_GLOBAL_TX_NAME = "default";
// 依赖: TransactionManager
private TransactionManager transactionManager;
private String xid;
private GlobalStatus status;
private GlobalTransactionRole role;
// commit最大重试次数
private static final int COMMIT_RETRY_COUNT = ConfigurationFactory.getInstance().getInt(
ConfigurationKeys.CLIENT_TM_COMMIT_RETRY_COUNT, DEFAULT_TM_COMMIT_RETRY_COUNT);
// rollback最大重试次数
private static final int ROLLBACK_RETRY_COUNT = ConfigurationFactory.getInstance().getInt(
ConfigurationKeys.CLIENT_TM_ROLLBACK_RETRY_COUNT, DEFAULT_TM_ROLLBACK_RETRY_COUNT);
// 构造器
DefaultGlobalTransaction() {
// xid为空
// 状态为:UnKnown(未开始)
// 角色为:GlobalTransactionRole.Launcher
this(null, GlobalStatus.UnKnown, GlobalTransactionRole.Launcher);
}
// 构造器
DefaultGlobalTransaction(String xid, GlobalStatus status, GlobalTransactionRole role) {
// 通过SPI获得:TransactionManager
this.transactionManager = TransactionManagerHolder.get();
this.xid = xid;
this.status = status;
this.role = role;
}
(4). DefaultGlobalTransaction.begin
@Override
public void begin() throws TransactionException {
begin(DEFAULT_GLOBAL_TX_TIMEOUT);
}
@Override
public void begin(int timeout) throws TransactionException {
begin(timeout, DEFAULT_GLOBAL_TX_NAME);
}
@Override
public void begin(int timeout, String name) throws TransactionException {
if (role != GlobalTransactionRole.Launcher) {
// 当前的角色为参与者是(Participant) xid是必须要先存在的
// if (xid == null) {
// throw new IllegalStateException();
// }
assertXIDNotNull(); // 若xid为空,抛出异常:IllegalStateException
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ignore Begin(): just involved in global transaction [{}]", xid);
}
// 直接返回了,代表XID不用再注册了
return;
}
// if (xid != null) {
// throw new IllegalStateException();
// }
assertXIDNull(); //若xid不为空(xid已经存在了),则抛出异常:IllegalStateException
// 从ThreadLocal获得xid(TX_XID)
String currentXid = RootContext.getXID();
if (currentXid != null) { // 存在,抛出异常
throw new IllegalStateException("Global transaction already exists," +
" can't begin a new global transaction, currentXid = " + currentXid);
}
// 上面的逻辑是:在角色为:GlobalTransactionRole.Launcher的情况下,xid必须要为空.否则,会进行检查
// *******************************************************
// 委托给了:DefaultTransactionManager进行处理
// 我在这里不详解,留一节在后面详解.
// *******************************************************
xid = transactionManager.begin(null, null, name, timeout);
// 设置状态为:Begin
status = GlobalStatus.Begin;
// 设置xid到ThreadLocal里
RootContext.bind(xid);
// 打印日志
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Begin new global transaction [{}]", xid);
}
}
(5). DefaultGlobalTransaction.commit
public void commit() throws TransactionException {
if (role == GlobalTransactionRole.Participant) {
// Participant has no responsibility of committing
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ignore Commit(): just involved in global transaction [{}]", xid);
}
return;
}
// if (xid == null) {
// throw new IllegalStateException();
// }
assertXIDNotNull(); // commit阶段了,xid是上不能为空的了
// 获得配置参数(commit的最大重试次数):
// client.tm.commitRetryCount = 5
int retry = COMMIT_RETRY_COUNT <= 0 ? DEFAULT_TM_COMMIT_RETRY_COUNT : COMMIT_RETRY_COUNT;
try {
// commit
while (retry > 0) {
try {
// *******************************************************
// 委托给了:DefaultTransactionManager进行处理
// 我在这里不详解,留一节在后面详解.
// *******************************************************
status = transactionManager.commit(xid);
break;
} catch (Throwable ex) {
LOGGER.error("Failed to report global commit [{}],Retry Countdown: {}, reason: {}", this.getXid(), retry, ex.getMessage());
retry--;
if (retry == 0) {
throw new TransactionException("Failed to report global commit", ex);
}
}
}
} finally {
if (xid.equals(RootContext.getXID())) {
suspend();
}
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("[{}] commit status: {}", xid, status);
}
}
(6). DefaultGlobalTransaction.rollback
public void rollback() throws TransactionException {
if (role == GlobalTransactionRole.Participant) {
// Participant has no responsibility of rollback
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Ignore Rollback(): just involved in global transaction [{}]", xid);
}
return;
}
// if (xid == null) {
// throw new IllegalStateException();
// }
assertXIDNotNull(); // rollback阶段,xid也不能为空
// 读取参数(rollback最大重试次数)
// client.tm.rollbackRetryCount = 5
int retry = ROLLBACK_RETRY_COUNT <= 0 ? DEFAULT_TM_ROLLBACK_RETRY_COUNT : ROLLBACK_RETRY_COUNT;
try {
while (retry > 0) {
try {
// *******************************************************
// 委托给了:DefaultTransactionManager进行处理
// 我在这里不详解,留一节在后面详解.
// *******************************************************
status = transactionManager.rollback(xid);
break;
} catch (Throwable ex) {
LOGGER.error("Failed to report global rollback [{}],Retry Countdown: {}, reason: {}", this.getXid(), retry, ex.getMessage());
retry--;
if (retry == 0) {
throw new TransactionException("Failed to report global rollback", ex);
}
}
}
} finally {
if (xid.equals(RootContext.getXID())) {
suspend();
}
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("[{}] rollback status: {}", xid, status);
}
}
(7). 总结
GlobalTransaction接受(begin/commit/rollback)请求,进行参数的校验,然后委托给:TransactionManager进行处理.