use of io.mycat.backend.mysql.nio.MySQLConnection in project Mycat-Server by MyCATApache.
the class RollbackNodeHandler method rollback.
public void rollback() {
final int initCount = session.getTargetCount();
lock.lock();
try {
reset(initCount);
} finally {
lock.unlock();
}
if (session.closed()) {
decrementCountToZero();
return;
}
// 执行
int started = 0;
for (final RouteResultsetNode node : session.getTargetKeys()) {
if (node == null) {
LOGGER.error("null is contained in RoutResultsetNodes, source = " + session.getSource());
continue;
}
final BackendConnection conn = session.getTarget(node);
if (conn != null) {
boolean isClosed = conn.isClosedOrQuit();
if (isClosed) {
session.getSource().writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, "receive rollback,but find backend con is closed or quit");
LOGGER.error(conn + "receive rollback,but fond backend con is closed or quit");
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("rollback job run for " + conn);
}
if (clearIfSessionClosed(session)) {
return;
}
conn.setResponseHandler(RollbackNodeHandler.this);
// support the XA rollback
if (session.getXaTXID() != null && conn instanceof MySQLConnection) {
MySQLConnection mysqlCon = (MySQLConnection) conn;
String xaTxId = session.getXaTXID() + ",'" + mysqlCon.getSchema() + "'";
// exeBatch cmd issue : the 2nd package can not receive the response
mysqlCon.execCmd("XA END " + xaTxId + ";");
mysqlCon.execCmd("XA ROLLBACK " + xaTxId + ";");
} else {
conn.rollback();
}
++started;
}
}
if (started < initCount && decrementCountBy(initCount - started)) {
/**
* assumption: only caused by front-end connection close. <br/>
* Otherwise, packet must be returned to front-end
*/
session.clearResources(true);
}
}
use of io.mycat.backend.mysql.nio.MySQLConnection in project Mycat-Server by MyCATApache.
the class MultiNodeCoordinator method okResponse.
@Override
public void okResponse(byte[] ok, BackendConnection conn) {
// process the XA Transatcion 2pc commit
if (conn instanceof MySQLConnection) {
MySQLConnection mysqlCon = (MySQLConnection) conn;
switch(mysqlCon.getXaStatus()) {
case TxState.TX_STARTED_STATE:
// should be wait all nodes ready ,then send xa commit to all nodes.
if (mysqlCon.batchCmdFinished()) {
String xaTxId = session.getXaTXID();
String cmd = "XA COMMIT " + xaTxId + ",'" + mysqlCon.getSchema() + "'";
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Start execute the cmd :" + cmd + ",current host:" + mysqlCon.getHost() + ":" + mysqlCon.getPort());
}
// recovery log
CoordinatorLogEntry coordinatorLogEntry = inMemoryRepository.get(xaTxId);
for (int i = 0; i < coordinatorLogEntry.participants.length; i++) {
LOGGER.debug("[In Memory CoordinatorLogEntry]" + coordinatorLogEntry.participants[i]);
if (coordinatorLogEntry.participants[i].resourceName.equals(conn.getSchema())) {
coordinatorLogEntry.participants[i].txState = TxState.TX_PREPARED_STATE;
}
}
inMemoryRepository.put(xaTxId, coordinatorLogEntry);
fileRepository.writeCheckpoint(inMemoryRepository.getAllCoordinatorLogEntries());
// send commit
mysqlCon.setXaStatus(TxState.TX_PREPARED_STATE);
mysqlCon.execCmd(cmd);
}
return;
case TxState.TX_PREPARED_STATE:
{
// recovery log
String xaTxId = session.getXaTXID();
CoordinatorLogEntry coordinatorLogEntry = inMemoryRepository.get(xaTxId);
for (int i = 0; i < coordinatorLogEntry.participants.length; i++) {
if (coordinatorLogEntry.participants[i].resourceName.equals(conn.getSchema())) {
coordinatorLogEntry.participants[i].txState = TxState.TX_COMMITED_STATE;
}
}
inMemoryRepository.put(xaTxId, coordinatorLogEntry);
fileRepository.writeCheckpoint(inMemoryRepository.getAllCoordinatorLogEntries());
// XA reset status now
mysqlCon.setXaStatus(TxState.TX_INITIALIZE_STATE);
break;
}
default:
}
}
if (this.cmdHandler.relaseConOnOK()) {
session.releaseConnection(conn);
} else {
session.releaseConnectionIfSafe(conn, LOGGER.isDebugEnabled(), false);
}
if (this.finished()) {
cmdHandler.okResponse(session, ok);
if (cmdHandler.isAutoClearSessionCons()) {
session.clearResources(false);
}
/* 1. 事务提交后,xa 事务结束 */
if (session.getXaTXID() != null) {
session.setXATXEnabled(false);
}
/* 2. preAcStates 为true,事务结束后,需要设置为true。preAcStates 为ac上一个状态 */
if (session.getSource().isPreAcStates()) {
session.getSource().setAutocommit(true);
}
}
}
Aggregations