Search in sources :

Example 1 with BranchTransactionException

use of io.seata.core.exception.BranchTransactionException in project seata by seata.

the class AbstractCore method branchCommit.

@Override
public BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
    try {
        BranchCommitRequest request = new BranchCommitRequest();
        request.setXid(branchSession.getXid());
        request.setBranchId(branchSession.getBranchId());
        request.setResourceId(branchSession.getResourceId());
        request.setApplicationData(branchSession.getApplicationData());
        request.setBranchType(branchSession.getBranchType());
        return branchCommitSend(request, globalSession, branchSession);
    } catch (IOException | TimeoutException e) {
        throw new BranchTransactionException(FailedToSendBranchCommitRequest, String.format("Send branch commit failed, xid = %s branchId = %s", branchSession.getXid(), branchSession.getBranchId()), e);
    }
}
Also used : IOException(java.io.IOException) FailedToSendBranchCommitRequest(io.seata.core.exception.TransactionExceptionCode.FailedToSendBranchCommitRequest) BranchCommitRequest(io.seata.core.protocol.transaction.BranchCommitRequest) BranchTransactionException(io.seata.core.exception.BranchTransactionException) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with BranchTransactionException

use of io.seata.core.exception.BranchTransactionException in project seata by seata.

the class AbstractUndoLogManager method undo.

/**
 * Undo.
 *
 * @param dataSourceProxy the data source proxy
 * @param xid             the xid
 * @param branchId        the branch id
 * @throws TransactionException the transaction exception
 */
@Override
public void undo(DataSourceProxy dataSourceProxy, String xid, long branchId) throws TransactionException {
    Connection conn = null;
    ResultSet rs = null;
    PreparedStatement selectPST = null;
    boolean originalAutoCommit = true;
    for (; ; ) {
        try {
            conn = dataSourceProxy.getPlainConnection();
            // The entire undo process should run in a local transaction.
            if (originalAutoCommit = conn.getAutoCommit()) {
                conn.setAutoCommit(false);
            }
            // Find UNDO LOG
            selectPST = conn.prepareStatement(SELECT_UNDO_LOG_SQL);
            selectPST.setLong(1, branchId);
            selectPST.setString(2, xid);
            rs = selectPST.executeQuery();
            boolean exists = false;
            while (rs.next()) {
                exists = true;
                // It is possible that the server repeatedly sends a rollback request to roll back
                // the same branch transaction to multiple processes,
                // ensuring that only the undo_log in the normal state is processed.
                int state = rs.getInt(ClientTableColumnsName.UNDO_LOG_LOG_STATUS);
                if (!canUndo(state)) {
                    if (LOGGER.isInfoEnabled()) {
                        LOGGER.info("xid {} branch {}, ignore {} undo_log", xid, branchId, state);
                    }
                    return;
                }
                String contextString = rs.getString(ClientTableColumnsName.UNDO_LOG_CONTEXT);
                Map<String, String> context = parseContext(contextString);
                byte[] rollbackInfo = getRollbackInfo(rs);
                String serializer = context == null ? null : context.get(UndoLogConstants.SERIALIZER_KEY);
                UndoLogParser parser = serializer == null ? UndoLogParserFactory.getInstance() : UndoLogParserFactory.getInstance(serializer);
                BranchUndoLog branchUndoLog = parser.decode(rollbackInfo);
                try {
                    // put serializer name to local
                    setCurrentSerializer(parser.getName());
                    List<SQLUndoLog> sqlUndoLogs = branchUndoLog.getSqlUndoLogs();
                    if (sqlUndoLogs.size() > 1) {
                        Collections.reverse(sqlUndoLogs);
                    }
                    for (SQLUndoLog sqlUndoLog : sqlUndoLogs) {
                        TableMeta tableMeta = TableMetaCacheFactory.getTableMetaCache(dataSourceProxy.getDbType()).getTableMeta(conn, sqlUndoLog.getTableName(), dataSourceProxy.getResourceId());
                        sqlUndoLog.setTableMeta(tableMeta);
                        AbstractUndoExecutor undoExecutor = UndoExecutorFactory.getUndoExecutor(dataSourceProxy.getDbType(), sqlUndoLog);
                        undoExecutor.executeOn(conn);
                    }
                } finally {
                    // remove serializer name
                    removeCurrentSerializer();
                }
            }
            if (exists) {
                deleteUndoLog(xid, branchId, conn);
                conn.commit();
                if (LOGGER.isInfoEnabled()) {
                    LOGGER.info("xid {} branch {}, undo_log deleted with {}", xid, branchId, State.GlobalFinished.name());
                }
            } else {
                insertUndoLogWithGlobalFinished(xid, branchId, UndoLogParserFactory.getInstance(), conn);
                conn.commit();
                if (LOGGER.isInfoEnabled()) {
                    LOGGER.info("xid {} branch {}, undo_log added with {}", xid, branchId, State.GlobalFinished.name());
                }
            }
            return;
        } catch (SQLIntegrityConstraintViolationException e) {
            // Possible undo_log has been inserted into the database by other processes, retrying rollback undo_log
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("xid {} branch {}, undo_log inserted, retry rollback", xid, branchId);
            }
        } catch (Throwable e) {
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException rollbackEx) {
                    LOGGER.warn("Failed to close JDBC resource while undo ... ", rollbackEx);
                }
            }
            throw new BranchTransactionException(BranchRollbackFailed_Retriable, String.format("Branch session rollback failed and try again later xid = %s branchId = %s %s", xid, branchId, e.getMessage()), e);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (selectPST != null) {
                    selectPST.close();
                }
                if (conn != null) {
                    if (originalAutoCommit) {
                        conn.setAutoCommit(true);
                    }
                    conn.close();
                }
            } catch (SQLException closeEx) {
                LOGGER.warn("Failed to close JDBC resource while undo ... ", closeEx);
            }
        }
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) SQLIntegrityConstraintViolationException(java.sql.SQLIntegrityConstraintViolationException) ResultSet(java.sql.ResultSet) TableMeta(io.seata.rm.datasource.sql.struct.TableMeta) BranchTransactionException(io.seata.core.exception.BranchTransactionException)

Example 3 with BranchTransactionException

use of io.seata.core.exception.BranchTransactionException in project XHuiCloud by sindaZeng.

the class AbstractCore method branchRegister.

@Override
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid, String applicationData, String lockKeys) throws TransactionException {
    GlobalSession globalSession = assertGlobalSessionNotNull(xid, false);
    return SessionHolder.lockAndExecute(globalSession, () -> {
        globalSessionStatusCheck(globalSession);
        globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
        BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, branchType, resourceId, applicationData, lockKeys, clientId);
        branchSessionLock(globalSession, branchSession);
        try {
            globalSession.addBranch(branchSession);
        } catch (RuntimeException ex) {
            branchSessionUnlock(branchSession);
            throw new BranchTransactionException(FailedToAddBranch, String.format("Failed to store branch xid = %s branchId = %s", globalSession.getXid(), branchSession.getBranchId()), ex);
        }
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Register branch successfully, xid = {}, branchId = {}, resourceId = {} ,lockKeys = {}", globalSession.getXid(), branchSession.getBranchId(), resourceId, lockKeys);
        }
        return branchSession.getBranchId();
    });
}
Also used : GlobalSession(io.seata.server.session.GlobalSession) BranchSession(io.seata.server.session.BranchSession) BranchTransactionException(io.seata.core.exception.BranchTransactionException)

Example 4 with BranchTransactionException

use of io.seata.core.exception.BranchTransactionException in project seata by seata.

the class AbstractCore method branchRegister.

@Override
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid, String applicationData, String lockKeys) throws TransactionException {
    GlobalSession globalSession = assertGlobalSessionNotNull(xid, false);
    return SessionHolder.lockAndExecute(globalSession, () -> {
        globalSessionStatusCheck(globalSession);
        globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
        BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, branchType, resourceId, applicationData, lockKeys, clientId);
        MDC.put(RootContext.MDC_KEY_BRANCH_ID, String.valueOf(branchSession.getBranchId()));
        branchSessionLock(globalSession, branchSession);
        try {
            globalSession.addBranch(branchSession);
        } catch (RuntimeException ex) {
            branchSessionUnlock(branchSession);
            throw new BranchTransactionException(FailedToAddBranch, String.format("Failed to store branch xid = %s branchId = %s", globalSession.getXid(), branchSession.getBranchId()), ex);
        }
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Register branch successfully, xid = {}, branchId = {}, resourceId = {} ,lockKeys = {}", globalSession.getXid(), branchSession.getBranchId(), resourceId, lockKeys);
        }
        return branchSession.getBranchId();
    });
}
Also used : GlobalSession(io.seata.server.session.GlobalSession) BranchSession(io.seata.server.session.BranchSession) BranchTransactionException(io.seata.core.exception.BranchTransactionException)

Example 5 with BranchTransactionException

use of io.seata.core.exception.BranchTransactionException in project seata by seata.

the class AbstractCore method branchRollback.

@Override
public BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
    try {
        BranchRollbackRequest request = new BranchRollbackRequest();
        request.setXid(branchSession.getXid());
        request.setBranchId(branchSession.getBranchId());
        request.setResourceId(branchSession.getResourceId());
        request.setApplicationData(branchSession.getApplicationData());
        request.setBranchType(branchSession.getBranchType());
        return branchRollbackSend(request, globalSession, branchSession);
    } catch (IOException | TimeoutException e) {
        throw new BranchTransactionException(FailedToSendBranchRollbackRequest, String.format("Send branch rollback failed, xid = %s branchId = %s", branchSession.getXid(), branchSession.getBranchId()), e);
    }
}
Also used : BranchRollbackRequest(io.seata.core.protocol.transaction.BranchRollbackRequest) FailedToSendBranchRollbackRequest(io.seata.core.exception.TransactionExceptionCode.FailedToSendBranchRollbackRequest) IOException(java.io.IOException) BranchTransactionException(io.seata.core.exception.BranchTransactionException) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

BranchTransactionException (io.seata.core.exception.BranchTransactionException)9 BranchSession (io.seata.server.session.BranchSession)4 GlobalSession (io.seata.server.session.GlobalSession)4 IOException (java.io.IOException)4 TimeoutException (java.util.concurrent.TimeoutException)4 BranchCommitRequest (io.seata.core.protocol.transaction.BranchCommitRequest)2 BranchRollbackRequest (io.seata.core.protocol.transaction.BranchRollbackRequest)2 FailedToSendBranchCommitRequest (io.seata.core.exception.TransactionExceptionCode.FailedToSendBranchCommitRequest)1 FailedToSendBranchRollbackRequest (io.seata.core.exception.TransactionExceptionCode.FailedToSendBranchRollbackRequest)1 TableMeta (io.seata.rm.datasource.sql.struct.TableMeta)1 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 SQLIntegrityConstraintViolationException (java.sql.SQLIntegrityConstraintViolationException)1