use of com.alibaba.cobar.net.mysql.BinaryPacket in project cobar by alibaba.
the class MySQLChannel method sendTxIsolation.
/**
* 发送事务级别设置
*/
private void sendTxIsolation(int txIsolation) throws IOException {
CommandPacket cmd = getTxIsolationCommand(txIsolation);
cmd.write(out);
out.flush();
BinaryPacket bin = receive();
switch(bin.data[0]) {
case OkPacket.FIELD_COUNT:
this.txIsolation = txIsolation;
break;
case ErrorPacket.FIELD_COUNT:
ErrorPacket err = new ErrorPacket();
err.read(bin);
throw new ErrorPacketException(new String(err.message, charset));
default:
throw new UnknownPacketException(bin.toString());
}
}
use of com.alibaba.cobar.net.mysql.BinaryPacket in project cobar by alibaba.
the class MultiNodeExecutor method handleRowData.
/**
* 处理RowData数据
*/
private void handleRowData(final RouteResultsetNode rrn, Channel c, BlockingSession ss) throws IOException {
final ServerConnection source = ss.getSource();
BinaryPacket bin = null;
int size = 0;
for (; ; ) {
bin = ((MySQLChannel) c).receive();
switch(bin.data[0]) {
case ErrorPacket.FIELD_COUNT:
c.setRunning(false);
handleFailure(ss, rrn, new BinaryErrInfo(((MySQLChannel) c), bin, source, rrn));
return;
case EOFPacket.FIELD_COUNT:
c.setRunning(false);
if (source.isAutocommit()) {
c = ss.getTarget().remove(rrn);
if (c != null) {
if (isFail.get() || source.isClosed()) {
/**
* this {@link Channel} might be closed by other
* thread in this condition, so that do not release
* this channel
*/
c.close();
} else {
c.release();
}
}
}
handleSuccessEOF(ss, bin);
return;
default:
// ROWS
bin.packetId = ++packetId;
buffer = bin.write(buffer, source);
size += bin.packetLength;
if (size > RECEIVE_CHUNK_SIZE) {
handleNext(rrn, c, ss);
return;
}
}
}
}
use of com.alibaba.cobar.net.mysql.BinaryPacket 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.net.mysql.BinaryPacket in project cobar by alibaba.
the class BlockingSession method clear.
/**
* MUST be called at the end of {@link NodeExecutor}
*
* @param pessimisticRelease true if this method might be invoked
* concurrently with {@link #kill()}
*/
private void clear(boolean pessimisticRelease) {
for (RouteResultsetNode rrn : target.keySet()) {
Channel c = target.remove(rrn);
// 通道不存在或者已被关闭
if (c == null || c.isClosed()) {
continue;
}
// 如果通道正在运行中,则关闭当前通道。
if (c.isRunning() || (pessimisticRelease && source.isClosed())) {
c.close();
continue;
}
// 非事务中的通道,直接释放资源。
if (c.isAutocommit()) {
c.release();
continue;
}
// 事务中的通道,需要先回滚后再释放资源。
MySQLChannel mc = (MySQLChannel) c;
try {
BinaryPacket bin = mc.rollback();
switch(bin.data[0]) {
case OkPacket.FIELD_COUNT:
mc.release();
break;
case ErrorPacket.FIELD_COUNT:
mc.close();
break;
default:
throw new UnknownPacketException(bin.toString());
}
} catch (IOException e) {
StringBuilder s = new StringBuilder();
LOGGER.warn(s.append(mc).append("rollback").toString(), e);
mc.close();
} catch (RuntimeException e) {
StringBuilder s = new StringBuilder();
LOGGER.warn(s.append(mc).append("rollback").toString(), e);
mc.close();
}
}
}
use of com.alibaba.cobar.net.mysql.BinaryPacket in project cobar by alibaba.
the class MySQLChannel method killChannel.
private void killChannel() {
MySQLChannel killChannel = null;
try {
killChannel = (MySQLChannel) dataSource.getChannel();
} catch (Exception e) {
LOGGER.error("killProcess failure for getting channel", e);
return;
}
CommandPacket killPacket = new CommandPacket();
killPacket.packetId = 0;
killPacket.command = MySQLPacket.COM_QUERY;
killPacket.arg = new StringBuilder("KILL ").append(threadId).toString().getBytes();
try {
killPacket.write(killChannel.out);
killChannel.out.flush();
BinaryPacket bin = new BinaryPacket();
bin.read(killChannel.in);
switch(bin.data[0]) {
case OkPacket.FIELD_COUNT:
killChannel.release();
break;
case ErrorPacket.FIELD_COUNT:
LOGGER.error("kill error! id:" + threadId + ", err=" + bin);
killChannel.release();
break;
default:
LOGGER.error("kill unknown response, id:" + threadId + "packet=" + bin);
killChannel.close();
}
} catch (IOException e) {
killChannel.close();
LOGGER.error("kill IOException, id:" + threadId, e);
}
}
Aggregations