Search in sources :

Example 21 with MySQLConnection

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);
    }
}
Also used : BackendConnection(io.mycat.backend.BackendConnection) RouteResultsetNode(io.mycat.route.RouteResultsetNode) MySQLConnection(io.mycat.backend.mysql.nio.MySQLConnection)

Example 22 with MySQLConnection

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);
        }
    }
}
Also used : MySQLConnection(io.mycat.backend.mysql.nio.MySQLConnection) CoordinatorLogEntry(io.mycat.backend.mysql.xa.CoordinatorLogEntry)

Aggregations

MySQLConnection (io.mycat.backend.mysql.nio.MySQLConnection)22 BackendConnection (io.mycat.backend.BackendConnection)6 JDBCConnection (io.mycat.backend.jdbc.JDBCConnection)6 CoordinatorLogEntry (io.mycat.backend.mysql.xa.CoordinatorLogEntry)4 NIOProcessor (io.mycat.net.NIOProcessor)4 RowDataPacket (io.mycat.net.mysql.RowDataPacket)4 RouteResultsetNode (io.mycat.route.RouteResultsetNode)4 PhysicalDBNode (io.mycat.backend.datasource.PhysicalDBNode)2 PhysicalDBPool (io.mycat.backend.datasource.PhysicalDBPool)2 PhysicalDatasource (io.mycat.backend.datasource.PhysicalDatasource)2 ParticipantLogEntry (io.mycat.backend.mysql.xa.ParticipantLogEntry)2 ConfigInitializer (io.mycat.config.ConfigInitializer)2 MycatCluster (io.mycat.config.MycatCluster)2 MycatConfig (io.mycat.config.MycatConfig)2 FirewallConfig (io.mycat.config.model.FirewallConfig)2 SchemaConfig (io.mycat.config.model.SchemaConfig)2 UserConfig (io.mycat.config.model.UserConfig)2 BackendAIOConnection (io.mycat.net.BackendAIOConnection)2 CommandPacket (io.mycat.net.mysql.CommandPacket)2 ServerConnection (io.mycat.server.ServerConnection)2