package com.easyooo.framework.support.transaction; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.transaction.CannotCreateTransactionException; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionStatus; import com.easyooo.framework.sharding.transaction.ChainedTransactionManager; /** * <p> * 系统事务管理器,这里只是对事务资源的一种扩充,而多数据源的事务依赖父类来完成 * </p> * <p> * 该类在数据库事务之后,将额外保证其它任何资源的事务一致性(这仅仅是一种理论上的事务一致性,一阶段事务) * 这部分资源包括只要实现了TransactionResource 接口的都将支持一阶段事务 * </p> * * @see TransactionResource * @see ChainedTransactionManager * * @author Killer */ public class BusinessResourceTransactionManager extends ChainedTransactionManager{ Logger logger = LoggerFactory.getLogger(getClass()); @Override public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { TransactionStatus status = super.getTransaction(definition); try { TransactionResourceManager.initSynchronization(); triggerBegin(status); } catch (Throwable e) { throw new CannotCreateTransactionException( "Unable to open the transaction", e); } return status; } @Override public void commit(TransactionStatus status) throws TransactionException { try{ super.commit(status); triggerCommit(status); }catch(TransactionException te){ triggerRollback(status); throw te; }finally{ // finally将保证cleanup被调用 cleanup(); } } @Override public void rollback(TransactionStatus status) throws TransactionException { try{ TransactionException rollbackException = null; try{ super.rollback(status); }catch(TransactionException te){ rollbackException = te; } // 保证触发资源回滚 triggerRollback(status); if(rollbackException != null){ throw rollbackException; } }finally{ cleanup(); } } /** * 触发事务开始方法 */ protected void triggerBegin(TransactionStatus status)throws Throwable{ Map<Object, TransactionResource> trs = TransactionResourceManager.getResourceMap(); for (TransactionResource tr : trs.values()) { tr.begin(); } } /** * 触发资源提交,使得每一个资源实例都触发提交, * 如果一旦出现异常,简单的记录日志,并继续下一资源的提交任务 * * @param status */ protected void triggerCommit(TransactionStatus status){ Map<Object, TransactionResource> trs = TransactionResourceManager.getResourceMap(); List<Throwable> commitException = new ArrayList<>(); List<TransactionResource> res = new ArrayList<>(); for (TransactionResource tr : trs.values()) { try { tr.commit(); } catch (Throwable e) { commitException.add(e); res.add(tr); logger.error("Resource commit error.", e); } } if(commitException.size() > 0){ logger.info("The transaction resource commit failure. total " + res.size()); } } /** * 触发资源回滚,使得每一个资源实例都触发回滚 * @param status */ protected void triggerRollback(TransactionStatus status){ Map<Object, TransactionResource> trs = TransactionResourceManager.getResourceMap(); List<Throwable> rollbackException = new ArrayList<>(); List<TransactionResource> res = new ArrayList<>(); for (TransactionResource tr : trs.values()) { try { tr.rollback(); } catch (Throwable e) { rollbackException.add(e); res.add(tr); logger.error("Resource rollback error.", e); } } if(rollbackException.size() > 0){ logger.info("The transaction resource rollback failure. total " + res.size()); } } /** * 事务资源的清理任务 * 清理线程变量 */ protected void cleanup(){ TransactionResourceManager.clear(); if(logger.isDebugEnabled()){ logger.debug("Transaction Resources has clean up."); } } }