use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class RollbackExecutor method _rollback.
private void _rollback(MySQLChannel mc, BlockingSession session) {
final ServerConnection source = session.getSource();
if (isFail.get() || source.isClosed()) {
mc.setRunning(false);
try {
throw new Exception("other task fails, rollback failed channel");
} catch (Exception e) {
handleException(mc, session, e);
}
return;
}
try {
BinaryPacket bin = mc.rollback();
switch(bin.data[0]) {
case OkPacket.FIELD_COUNT:
mc.setRunning(false);
if (decrementCountBy(1)) {
try {
if (isFail.get()) {
// some other tasks failed
session.clear();
source.writeErrMessage(ErrorCode.ER_YES, "rollback error!");
} else {
// all tasks are successful
session.release();
ByteBuffer buffer = source.allocate();
source.write(bin.write(buffer, source));
}
} catch (Exception e) {
LOGGER.warn("exception happens in success notification: " + source, e);
}
}
break;
case ErrorPacket.FIELD_COUNT:
isFail.set(true);
if (decrementCountBy(1)) {
try {
session.clear();
LOGGER.warn(mc.getErrLog("rollback", mc.getErrMessage(bin), source));
ByteBuffer buffer = source.allocate();
source.write(bin.write(buffer, source));
} catch (Exception e) {
LOGGER.warn("exception happens in failure notification: " + source, e);
}
}
break;
default:
throw new UnknownPacketException(bin.toString());
}
} catch (IOException e) {
mc.close();
handleException(mc, session, e);
} catch (RuntimeException e) {
mc.close();
handleException(mc, session, e);
}
}
use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class RollbackExecutor method rollback.
/**
* 事务回滚
*/
public void rollback(final BlockingSession session) {
final ServerConnection source = session.getSource();
final ConcurrentMap<RouteResultsetNode, Channel> target = session.getTarget();
final int initNodeCount = target.size();
if (initNodeCount <= 0) {
ByteBuffer buffer = source.allocate();
source.write(source.writeToBuffer(OkPacket.OK, buffer));
return;
}
// 初始化
final ReentrantLock lock = this.lock;
lock.lock();
try {
this.isFail.set(false);
this.nodeCount = initNodeCount;
} finally {
lock.unlock();
}
if (source.isClosed()) {
decrementCountToZero();
return;
}
// 执行
Executor committer = source.getProcessor().getCommitter();
int started = 0;
for (RouteResultsetNode rrn : target.keySet()) {
final MySQLChannel mc = (MySQLChannel) target.get(rrn);
if (mc != null) {
mc.setRunning(true);
committer.execute(new Runnable() {
@Override
public void run() {
_rollback(mc, session);
}
});
++started;
}
}
if (started < initNodeCount) {
decrementCountBy(initNodeCount - started);
}
}
use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class SingleNodeExecutor method newExecute.
/**
* 新数据通道的执行
*/
private void newExecute(final RouteResultsetNode rrn, final BlockingSession ss, final int flag) {
final ServerConnection sc = ss.getSource();
// 检查数据节点是否存在
CobarConfig conf = CobarServer.getInstance().getConfig();
final MySQLDataNode dn = conf.getDataNodes().get(rrn.getName());
if (dn == null) {
LOGGER.warn(new StringBuilder().append(sc).append(rrn).toString(), new UnknownDataNodeException());
handleError(ErrorCode.ER_BAD_DB_ERROR, "Unknown dataNode '" + rrn.getName() + "'", ss);
return;
}
// 提交执行任务
sc.getProcessor().getExecutor().execute(new Runnable() {
@Override
public void run() {
// 取得数据通道
int i = rrn.getReplicaIndex();
Channel c = null;
try {
c = (i == DEFAULT_REPLICA_INDEX) ? dn.getChannel() : dn.getChannel(i);
} catch (Exception e) {
LOGGER.warn(new StringBuilder().append(sc).append(rrn).toString(), e);
String msg = e.getMessage();
handleError(ErrorCode.ER_BAD_DB_ERROR, msg == null ? e.getClass().getSimpleName() : msg, ss);
return;
}
// 检查连接是否已关闭。
if (sc.isClosed()) {
c.release();
endRunning();
return;
}
// 绑定数据通道
c.setRunning(true);
Channel old = ss.getTarget().put(rrn, c);
if (old != null && old != c) {
old.close();
}
// 执行
execute0(rrn, ss, c, flag);
}
});
}
use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class SingleNodeExecutor method handleNext.
/**
* 下一个数据接收任务
*/
private void handleNext(final RouteResultsetNode rrn, final BlockingSession ss, final MySQLChannel mc, final ByteBuffer bb, final byte id) {
final ServerConnection sc = ss.getSource();
sc.getProcessor().getExecutor().execute(new Runnable() {
@Override
public void run() {
try {
handleRowData(rrn, ss, mc, bb, id);
} catch (IOException e) {
LOGGER.warn(new StringBuilder().append(sc).append(rrn).toString(), e);
mc.close();
String msg = e.getMessage();
handleError(ErrorCode.ER_YES, msg == null ? e.getClass().getSimpleName() : msg, ss);
} catch (RuntimeException e) {
LOGGER.warn(new StringBuilder().append(sc).append(rrn).toString(), e);
mc.close();
String msg = e.getMessage();
handleError(ErrorCode.ER_YES, msg == null ? e.getClass().getSimpleName() : msg, ss);
}
}
});
}
use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class SingleNodeExecutor method handleResultSet.
/**
* 处理结果集数据
*/
private void handleResultSet(RouteResultsetNode rrn, BlockingSession ss, MySQLChannel mc, BinaryPacket bin, int flag) throws IOException {
final ServerConnection sc = ss.getSource();
// HEADER
bin.packetId = ++packetId;
List<MySQLPacket> headerList = new LinkedList<MySQLPacket>();
headerList.add(bin);
for (; ; ) {
bin = mc.receive();
switch(bin.data[0]) {
case ErrorPacket.FIELD_COUNT:
{
LOGGER.warn(mc.getErrLog(rrn.getStatement(), mc.getErrMessage(bin), sc));
mc.setRunning(false);
if (mc.isAutocommit()) {
ss.clear();
}
endRunning();
// ERROR_PACKET
bin.packetId = ++packetId;
sc.write(bin.write(sc.allocate(), sc));
return;
}
case EOFPacket.FIELD_COUNT:
{
// FIELD_EOF
bin.packetId = ++packetId;
ByteBuffer bb = sc.allocate();
for (MySQLPacket packet : headerList) {
bb = packet.write(bb, sc);
}
bb = bin.write(bb, sc);
headerList = null;
handleRowData(rrn, ss, mc, bb, packetId);
return;
}
default:
// FIELDS
bin.packetId = ++packetId;
switch(flag) {
case RouteResultset.REWRITE_FIELD:
StringBuilder fieldName = new StringBuilder();
fieldName.append("Tables_in_").append(ss.getSource().getSchema());
FieldPacket field = PacketUtil.getField(bin, fieldName.toString());
headerList.add(field);
break;
default:
headerList.add(bin);
}
}
}
}
Aggregations