ByteTCC源码分析(一)

/**
 * Copyright 2014-2016 yangming.liu<bytefox@126.com>.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, see <http://www.gnu.org/licenses/>.
 */
package org.bytesoft.bytetcc;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

import org.apache.commons.lang3.StringUtils;
import org.bytesoft.bytejta.supports.jdbc.RecoveredResource;
import org.bytesoft.bytejta.supports.resource.RemoteResourceDescriptor;
import org.bytesoft.bytejta.supports.wire.RemoteCoordinator;
import org.bytesoft.bytetcc.supports.resource.LocalResourceCleaner;
import org.bytesoft.common.utils.ByteUtils;
import org.bytesoft.common.utils.CommonUtils;
import org.bytesoft.compensable.CompensableBeanFactory;
import org.bytesoft.compensable.CompensableInvocation;
import org.bytesoft.compensable.CompensableTransaction;
import org.bytesoft.compensable.ContainerContext;
import org.bytesoft.compensable.TransactionContext;
import org.bytesoft.compensable.archive.CompensableArchive;
import org.bytesoft.compensable.archive.TransactionArchive;
import org.bytesoft.compensable.logging.CompensableLogger;
import org.bytesoft.transaction.CommitRequiredException;
import org.bytesoft.transaction.RollbackRequiredException;
import org.bytesoft.transaction.Transaction;
import org.bytesoft.transaction.TransactionRepository;
import org.bytesoft.transaction.archive.XAResourceArchive;
import org.bytesoft.transaction.supports.TransactionListener;
import org.bytesoft.transaction.supports.TransactionListenerAdapter;
import org.bytesoft.transaction.supports.TransactionResourceListener;
import org.bytesoft.transaction.supports.resource.XAResourceDescriptor;
import org.bytesoft.transaction.supports.serialize.XAResourceDeserializer;
import org.bytesoft.transaction.xa.TransactionXid;
import org.bytesoft.transaction.xa.XidFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CompensableTransactionImpl extends TransactionListenerAdapter implements CompensableTransaction {
	static final Logger logger = LoggerFactory.getLogger(CompensableTransactionImpl.class);

	private final TransactionContext transactionContext;
	private final List<CompensableArchive> archiveList = new ArrayList<CompensableArchive>();
	private final Map<String, XAResourceArchive> resourceMap = new HashMap<String, XAResourceArchive>();
	private final List<XAResourceArchive> resourceList = new ArrayList<XAResourceArchive>();
	private final Map<String, XAResourceArchive> applicationMap = new HashMap<String, XAResourceArchive>();
	private final Map<Thread, Transaction> transactionMap = new ConcurrentHashMap<Thread, Transaction>(4);
	private CompensableBeanFactory beanFactory;

	private int transactionVote;
	private int transactionStatus = Status.STATUS_ACTIVE;
	/* current comensable-decision in confirm/cancel phase. */
	private transient Boolean positive;
	/* current compense-archive in confirm/cancel phase. */
	private transient CompensableArchive archive;

	/* current compensable-archive list in try phase. */
	private transient final List<CompensableArchive> currentArchiveList = new ArrayList<CompensableArchive>();
	private transient final Map<Xid, List<CompensableArchive>> archiveMap = new HashMap<Xid, List<CompensableArchive>>();

	private boolean participantStickyRequired;

	private Map<String, Serializable> variables = new HashMap<String, Serializable>();

	private Thread currentThread;
	private final Lock lock = new ReentrantLock();

	public CompensableTransactionImpl(TransactionContext txContext) {
		this.transactionContext = txContext;
	}

	public TransactionArchive getTransactionArchive() {
		TransactionArchive transactionArchive = new TransactionArchive();
		transactionArchive.setVariables(this.variables);
		transactionArchive.setCoordinator(this.transactionContext.isCoordinator());
		transactionArchive.setPropagated(this.transactionContext.isPropagated());
		transactionArchive.setCompensable(this.transactionContext.isCompensable());
		transactionArchive.setCompensableStatus(this.transactionStatus);
		transactionArchive.setVote(this.transactionVote);
		transactionArchive.setXid(this.transactionContext.getXid());
		transactionArchive.getRemoteResources().addAll(this.resourceList);
		transactionArchive.getCompensableResourceList().addAll(this.archiveList);
		transactionArchive.setPropagatedBy(this.transactionContext.getPropagatedBy());
		return transactionArchive;
	}

	public synchronized void participantCommit(boolean opc) throws RollbackException, HeuristicMixedException,
			HeuristicRollbackException, SecurityException, IllegalStateException, CommitRequiredException, SystemException {

		// Recover if transaction is recovered from tx-log.
		this.recoverIfNecessary();

		if (this.transactionStatus != Status.STATUS_COMMITTED) {
			this.fireCommit(); // TODO
		}

	}
        // 当前事务节点,进行commit操作(该方法由监听器回调调用)
	public synchronized void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
			SecurityException, IllegalStateException, SystemException {

		if (this.transactionStatus == Status.STATUS_ACTIVE) {   // 事务状态:   活跃有效
			this.fireCommit();
		} else if (this.transactionStatus == Status.STATUS_MARKED_ROLLBACK) {   // 事务状态:  标志回滚
			this.fireRollback();
			throw new HeuristicRollbackException();
		} else if (this.transactionStatus == Status.STATUS_ROLLEDBACK) /* should never happen */ {   // 事务状态:异常回滚,理论上不会出现这种情况
			throw new RollbackException();
		} else if (this.transactionStatus == Status.STATUS_COMMITTED) /* should never happen */ { // 事务状态: 已经提交,理论上不会出现这种情况
			logger.debug("Current transaction has already been committed.");
		} else {
			throw new IllegalStateException();
		}

	}
        // 执行发送提交
	private void fireCommit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException,
			IllegalStateException, SystemException {
		CompensableLogger compensableLogger = this.beanFactory.getCompensableLogger();
		this.transactionContext.setCompensating(true); // 正在补偿
		this.transactionStatus = Status.STATUS_COMMITTING;   // 事务状态:节点事务提交中
		compensableLogger.updateTransaction(this.getTransactionArchive());  // 更新记录一下事务归档  

		SystemException systemEx = null;
		try {
			this.fireNativeParticipantConfirm();   // 执行本地事务参与者 提交节点事务
		} catch (SystemException ex) {
			systemEx = ex;

			logger.info("{}| confirm native branchs failed!",
					ByteUtils.byteArrayToString(this.transactionContext.getXid().getGlobalTransactionId()), ex);
		} catch (RuntimeException ex) {
			systemEx = new SystemException();
			systemEx.initCause(ex);

			logger.info("{}| confirm native branchs failed!",
					ByteUtils.byteArrayToString(this.transactionContext.getXid().getGlobalTransactionId()), ex);
		}

		try {
			this.fireRemoteParticipantConfirm();       // 执行远程事务参与者 提交节点事务
		} catch (HeuristicMixedException ex) {
			logger.info("{}| confirm remote branchs failed!",
					ByteUtils.byteArrayToString(this.transactionContext.getXid().getGlobalTransactionId()), ex);
			throw ex;
		} catch (HeuristicRollbackException ex) {
			logger.info("{}| confirm remote branchs failed!",
					ByteUtils.byteArrayToString(this.transactionContext.getXid().getGlobalTransactionId()), ex);
			throw ex;
		} catch (SystemException ex) {
			logger.info("{}| confirm remote branchs failed!",
					ByteUtils.byteArrayToString(this.transactionContext.getXid().getGlobalTransactionId()), ex);
			throw ex;
		} catch (RuntimeException ex) {
			logger.info("{}| confirm remote branchs failed!",
					ByteUtils.byteArrayToString(this.transactionContext.getXid().getGlobalTransactionId()), ex);
			throw ex;
		}

		if (systemEx != null) {
			throw systemEx;
		} else {
			this.transactionStatus = Status.STATUS_COMMITTED;   // 提交完成,事务状态更新为 已提交
			compensableLogger.updateTransaction(this.getTransactionArchive());  // 更新记录一下节点事务归档
			logger.info("{}| compensable transaction committed!",
					ByteUtils.byteArrayToString(transactionContext.getXid().getGlobalTransactionId()));
		}

	}

	public synchronized void recoveryCommit() throws CommitRequiredException, SystemException {

		this.recoverIfNecessary(); // Recover if transaction is recovered from tx-log.

		try {
			this.fireCommit();
		} catch (SecurityException ex) {
			logger.error("{}| confirm native/remote branchs failed!",
					ByteUtils.byteArrayToString(this.transactionContext.getXid().getGlobalTransactionId()), ex);
			SystemException sysEx = new SystemException();
			sysEx.initCause(ex);
			throw sysEx;
		} catch (RollbackException ex) {
			logger.error("{}| confirm native/remote branchs failed!",
					ByteUtils.byteArrayToString(this.transactionContext.getXid().getGlobalTransactionId()), ex);
			SystemException sysEx = new SystemException();
			sysEx.initC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值