package com.meidusa.amoeba.mysql.handler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import org.apache.log4j.Logger;
import com.meidusa.amoeba.mysql.net.MysqlClientConnection;
import com.meidusa.amoeba.mysql.net.MysqlConnection;
import com.meidusa.amoeba.mysql.net.MysqlServerConnection;
import com.meidusa.amoeba.mysql.net.packet.ConstantPacketBuffer;
import com.meidusa.amoeba.net.Connection;
import com.meidusa.amoeba.net.poolable.ObjectPool;
import com.meidusa.amoeba.parser.statement.Statement;
import com.meidusa.amoeba.route.Request;
import com.meidusa.amoeba.util.StringUtil;
/**
* 对于事务模式的commit和rollback语句,直接发往set autocommit = 0语句后,所有路由过的连接
* 对于前端来说,像是和后端server connection建立了某种粘性
*
* 这个handler主要是处理commit、rollback、xa end、xa prepare、xa commite这些事务结束性语句
* 这些语句不需要再次路由,直接从连接缓存map中取
*
* @author WangFei
*
*/
public class StickyForTransactionHandler extends QueryCommandMessageHandler {
public static Logger logger = Logger.getLogger(StickyForTransactionHandler.class);
@Override
public synchronized void startSession() throws Exception {
Collection<MysqlConnection> resources = source.getStickyConnMap().values();
if(logger.isInfoEnabled()){
logger.info("sticky session start[type="+this.command.command+"]:ip="+this.source.getSocketId()+",handlerId="+this.hashCode()
+",time="+(System.currentTimeMillis()-createTime)
+",request="+(getRequest() ==null ? null: getRequest().toString()));
}
// 如果管理的资源列表为空,那么直接结束掉session
if (resources != null && resources.size() > 0) {
StringBuilder logAllResource = new StringBuilder();
ArrayList<String> conns = new ArrayList<String>();
logAllResource.append((getRequest() ==null ? null: getRequest().toString()) + " to " + resources.size() + " conns ");
for(Connection conn : resources) {
if (conn instanceof MysqlServerConnection) {
handlerMap.put(conn, conn.getMessageHandler());
if(conn.getMessageHandler() instanceof CommandMessageHandler){
logger.error("current handler="+conn.getMessageHandler().toString()+",");
}
conn.setMessageHandler(this);
commandQueue.connStatusMap.put((MysqlServerConnection) conn, newConnectionStatuts(conn));
conns.add(conn.hashCode()+"");
}
}
logAllResource.append(StringUtil.join(Arrays.asList(conns), ","));
if (logger.isInfoEnabled()) {
logger.info(logAllResource.toString());
}
this.started = true;
appendPreMainCommand();
this.commandQueue.appendCommand(info, true);
startNextCommand();
}
else {
source.postMessage(ConstantPacketBuffer.STATIC_OK_BUFFER);
if(!isEnded()){
synchronized (this) {
if(!ended){
ended = true;
}else{
return;
}
}
}
if(logger.isInfoEnabled()){
logger.info("sticky session end[type="+this.command.command+"],but it is not executed:ip="+this.source.getSocketId()
+",handlerId="+this.hashCode()
+",request="+(getRequest() ==null ? null: getRequest().toString()));
}
}
}
public StickyForTransactionHandler(MysqlClientConnection source, byte[] query,
Statement statment, ObjectPool[] pools, Request request, long timeout) {
super(source, query, statment, pools, request, timeout);
}
}