package com.taobao.tddl.repo.mysql.executor; import java.util.concurrent.Future; import com.taobao.tddl.common.exception.TddlException; import com.taobao.tddl.common.model.Group; import com.taobao.tddl.common.model.lifecycle.AbstractLifecycle; import com.taobao.tddl.executor.common.ExecutionContext; import com.taobao.tddl.executor.common.ExecutorContext; import com.taobao.tddl.executor.common.TransactionConfig; import com.taobao.tddl.executor.cursor.ISchematicCursor; import com.taobao.tddl.executor.cursor.ResultCursor; import com.taobao.tddl.executor.spi.ICommandHandler; import com.taobao.tddl.executor.spi.ICommandHandlerFactory; import com.taobao.tddl.executor.spi.IGroupExecutor; import com.taobao.tddl.executor.spi.IRepository; import com.taobao.tddl.executor.spi.ITransaction; import com.taobao.tddl.group.jdbc.TGroupDataSource; import com.taobao.tddl.optimizer.core.plan.IDataNodeExecutor; /** * 为TGroupDatasource实现的groupexecutor * 因为TGroupDatasource中已经做了主备切换等功能,所以TddlGroupExecutor只是简单的执行sql * * @author mengshi.sunmengshi 2013-12-6 下午2:39:18 * @since 5.0.0 */ public class TddlGroupExecutor extends AbstractLifecycle implements IGroupExecutor { public static final String TRANSACTION_GROUP_KEY = "GROUP_KEY"; private IRepository repo; /** * 可能是个datasource ,也可能是个rpc客户端。放在一起的原因是 */ private Object remotingExecutableObject; private Group group; public TddlGroupExecutor(IRepository repo){ this.repo = repo; } protected void doInit() throws TddlException { super.doInit(); } protected void doDestory() throws TddlException { if (remotingExecutableObject instanceof TGroupDataSource) { try { ((TGroupDataSource) remotingExecutableObject).destroyDataSource(); } catch (Exception e) { throw new TddlException(e); } } } @Override public ISchematicCursor execByExecPlanNode(IDataNodeExecutor qc, ExecutionContext executionContext) throws TddlException { executionContext.setCurrentRepository(repo); getTransaction(executionContext, qc); ISchematicCursor returnCursor = null; returnCursor = executeInner(qc, executionContext); return returnCursor; } @Override public Future<ISchematicCursor> execByExecPlanNodeFuture(IDataNodeExecutor qc, ExecutionContext executionContext) throws TddlException { return ExecutorContext.getContext().getTopologyExecutor().execByExecPlanNodeFuture(qc, executionContext); } public ISchematicCursor executeInner(IDataNodeExecutor executor, ExecutionContext executionContext) throws TddlException { // 允许远程执行。在cursor里面所依赖的执行器,从本地的换为远程的。并要注意远程事务处理过程中的兼容。 // 目前的处理方式是,走到这里的远程执行,不允许出现事务。。。出现就丢异常 ICommandHandlerFactory commandExecutorFactory = this.repo.getCommandExecutorFactory(); // 核心方法,用于根据当前executor,拿到对应的处理Handler ICommandHandler commandHandler = commandExecutorFactory.getCommandHandler(executor, executionContext); // command模式命令。 return commandHandler.handle(executor, executionContext); } public void getTransaction(ExecutionContext executionContext, IDataNodeExecutor targetExecutor) throws TddlException { if (executionContext.getTransaction() != null) { return; } IRepository repo = executionContext.getCurrentRepository(); // 如果有外部的 TransactionConfig tc = TransactionConfig.DEFAULT; ITransaction trans = repo.beginTransaction(tc); trans.setAutoCommit(executionContext.isAutoCommit()); executionContext.setTransaction(trans); // 将groupNode 放入执行的上下文 String groupNode = targetExecutor.getDataNode(); executionContext.setTransactionGroup(groupNode); } @Override public ResultCursor commit(ExecutionContext executionContext) throws TddlException { ResultCursor rc = new ResultCursor(null, executionContext); if (executionContext.getTransactionGroup() == null) { return rc; } executionContext.getTransaction().commit(); return rc; } @Override public ResultCursor rollback(ExecutionContext executionContext) throws TddlException { ResultCursor rc = new ResultCursor(null, executionContext); if (executionContext.getTransactionGroup() == null) { return rc; } executionContext.getTransaction().rollback(); return rc; } @Override public Future<ResultCursor> commitFuture(ExecutionContext executionContext) throws TddlException { return ExecutorContext.getContext().getTopologyExecutor().commitFuture(executionContext); } @Override public Future<ResultCursor> rollbackFuture(ExecutionContext executionContext) throws TddlException { return ExecutorContext.getContext().getTopologyExecutor().rollbackFuture(executionContext); } @Override public Group getGroupInfo() { return this.group; } public Object getRemotingExecutableObject() { return remotingExecutableObject; } public void setGroup(Group group) { this.group = group; } public void setRemotingExecutableObject(Object remotingExecutableObject) { this.remotingExecutableObject = remotingExecutableObject; } @Override public String toString() { return "GroupExecutor [groupName=" + group.getName() + ", type=" + group.getType() + ", remotingExecutableObject=" + remotingExecutableObject + "]"; } }