Search in sources :

Example 26 with ShouldNeverHappenException

use of io.seata.common.exception.ShouldNeverHappenException in project seata by seata.

the class PostgresqlUndoUpdateExecutor method buildUndoSQL.

@Override
protected String buildUndoSQL() {
    TableRecords beforeImage = sqlUndoLog.getBeforeImage();
    List<Row> beforeImageRows = beforeImage.getRows();
    if (CollectionUtils.isEmpty(beforeImageRows)) {
        // TODO
        throw new ShouldNeverHappenException("Invalid UNDO LOG");
    }
    Row row = beforeImageRows.get(0);
    List<Field> nonPkFields = row.nonPrimaryKeys();
    // update sql undo log before image all field come from table meta. need add escape.
    // see BaseTransactionalExecutor#buildTableRecords
    String updateColumns = nonPkFields.stream().map(field -> ColumnUtils.addEscape(field.getName(), JdbcConstants.POSTGRESQL) + " = ?").collect(Collectors.joining(", "));
    List<String> pkNameList = getOrderedPkList(beforeImage, row, JdbcConstants.POSTGRESQL).stream().map(e -> e.getName()).collect(Collectors.toList());
    String whereSql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, JdbcConstants.POSTGRESQL);
    return String.format(UPDATE_SQL_TEMPLATE, sqlUndoLog.getTableName(), updateColumns, whereSql);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) List(java.util.List) ColumnUtils(io.seata.rm.datasource.ColumnUtils) Field(io.seata.rm.datasource.sql.struct.Field) AbstractUndoExecutor(io.seata.rm.datasource.undo.AbstractUndoExecutor) CollectionUtils(io.seata.common.util.CollectionUtils) SqlGenerateUtils(io.seata.rm.datasource.SqlGenerateUtils) Row(io.seata.rm.datasource.sql.struct.Row) JdbcConstants(io.seata.sqlparser.util.JdbcConstants) Collectors(java.util.stream.Collectors) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) SQLUndoLog(io.seata.rm.datasource.undo.SQLUndoLog) Field(io.seata.rm.datasource.sql.struct.Field) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) Row(io.seata.rm.datasource.sql.struct.Row)

Example 27 with ShouldNeverHappenException

use of io.seata.common.exception.ShouldNeverHappenException in project seata by seata.

the class OracleUndoUpdateExecutor method buildUndoSQL.

@Override
protected String buildUndoSQL() {
    TableRecords beforeImage = sqlUndoLog.getBeforeImage();
    List<Row> beforeImageRows = beforeImage.getRows();
    if (CollectionUtils.isEmpty(beforeImageRows)) {
        // TODO
        throw new ShouldNeverHappenException("Invalid UNDO LOG");
    }
    Row row = beforeImageRows.get(0);
    List<Field> nonPkFields = row.nonPrimaryKeys();
    // update sql undo log before image all field come from table meta. need add escape.
    // see BaseTransactionalExecutor#buildTableRecords
    String updateColumns = nonPkFields.stream().map(field -> ColumnUtils.addEscape(field.getName(), JdbcConstants.ORACLE) + " = ?").collect(Collectors.joining(", "));
    List<String> pkNameList = getOrderedPkList(beforeImage, row, JdbcConstants.ORACLE).stream().map(e -> e.getName()).collect(Collectors.toList());
    String whereSql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, JdbcConstants.ORACLE);
    return String.format(UPDATE_SQL_TEMPLATE, sqlUndoLog.getTableName(), updateColumns, whereSql);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) List(java.util.List) ColumnUtils(io.seata.rm.datasource.ColumnUtils) Field(io.seata.rm.datasource.sql.struct.Field) AbstractUndoExecutor(io.seata.rm.datasource.undo.AbstractUndoExecutor) CollectionUtils(io.seata.common.util.CollectionUtils) SqlGenerateUtils(io.seata.rm.datasource.SqlGenerateUtils) Row(io.seata.rm.datasource.sql.struct.Row) JdbcConstants(io.seata.sqlparser.util.JdbcConstants) Collectors(java.util.stream.Collectors) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) SQLUndoLog(io.seata.rm.datasource.undo.SQLUndoLog) Field(io.seata.rm.datasource.sql.struct.Field) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) Row(io.seata.rm.datasource.sql.struct.Row)

Example 28 with ShouldNeverHappenException

use of io.seata.common.exception.ShouldNeverHappenException in project seata by seata.

the class MySQLUndoInsertExecutor method buildUndoSQL.

/**
 * Undo Inset.
 *
 * @return sql
 */
@Override
protected String buildUndoSQL() {
    TableRecords afterImage = sqlUndoLog.getAfterImage();
    List<Row> afterImageRows = afterImage.getRows();
    if (CollectionUtils.isEmpty(afterImageRows)) {
        throw new ShouldNeverHappenException("Invalid UNDO LOG");
    }
    return generateDeleteSql(afterImageRows, afterImage);
}
Also used : TableRecords(io.seata.rm.datasource.sql.struct.TableRecords) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) Row(io.seata.rm.datasource.sql.struct.Row)

Example 29 with ShouldNeverHappenException

use of io.seata.common.exception.ShouldNeverHappenException in project seata by seata.

the class TransactionalTemplate method execute.

/**
 * Execute object.
 *
 * @param business the business
 * @return the object
 * @throws TransactionalExecutor.ExecutionException the execution exception
 */
public Object execute(TransactionalExecutor business) throws Throwable {
    // 1. Get transactionInfo
    TransactionInfo txInfo = business.getTransactionInfo();
    if (txInfo == null) {
        throw new ShouldNeverHappenException("transactionInfo does not exist");
    }
    // 1.1 Get current transaction, if not null, the tx role is 'GlobalTransactionRole.Participant'.
    GlobalTransaction tx = GlobalTransactionContext.getCurrent();
    // 1.2 Handle the transaction propagation.
    Propagation propagation = txInfo.getPropagation();
    SuspendedResourcesHolder suspendedResourcesHolder = null;
    try {
        switch(propagation) {
            case NOT_SUPPORTED:
                // If transaction is existing, suspend it.
                if (existingTransaction(tx)) {
                    suspendedResourcesHolder = tx.suspend();
                }
                // Execute without transaction and return.
                return business.execute();
            case REQUIRES_NEW:
                // If transaction is existing, suspend it, and then begin new transaction.
                if (existingTransaction(tx)) {
                    suspendedResourcesHolder = tx.suspend();
                    tx = GlobalTransactionContext.createNew();
                }
                // Continue and execute with new transaction
                break;
            case SUPPORTS:
                // If transaction is not existing, execute without transaction.
                if (notExistingTransaction(tx)) {
                    return business.execute();
                }
                // Continue and execute with new transaction
                break;
            case REQUIRED:
                // else continue and execute with new transaction.
                break;
            case NEVER:
                // If transaction is existing, throw exception.
                if (existingTransaction(tx)) {
                    throw new TransactionException(String.format("Existing transaction found for transaction marked with propagation 'never', xid = %s", tx.getXid()));
                } else {
                    // Execute without transaction and return.
                    return business.execute();
                }
            case MANDATORY:
                // If transaction is not existing, throw exception.
                if (notExistingTransaction(tx)) {
                    throw new TransactionException("No existing transaction found for transaction marked with propagation 'mandatory'");
                }
                // Continue and execute with current transaction.
                break;
            default:
                throw new TransactionException("Not Supported Propagation:" + propagation);
        }
        // 1.3 If null, create new transaction with role 'GlobalTransactionRole.Launcher'.
        if (tx == null) {
            tx = GlobalTransactionContext.createNew();
        }
        // set current tx config to holder
        GlobalLockConfig previousConfig = replaceGlobalLockConfig(txInfo);
        try {
            // 2. If the tx role is 'GlobalTransactionRole.Launcher', send the request of beginTransaction to TC,
            // else do nothing. Of course, the hooks will still be triggered.
            beginTransaction(txInfo, tx);
            Object rs;
            try {
                // Do Your Business
                rs = business.execute();
            } catch (Throwable ex) {
                // 3. The needed business exception to rollback.
                completeTransactionAfterThrowing(txInfo, tx, ex);
                throw ex;
            }
            // 4. everything is fine, commit.
            commitTransaction(tx);
            return rs;
        } finally {
            // 5. clear
            resumeGlobalLockConfig(previousConfig);
            triggerAfterCompletion();
            cleanUp();
        }
    } finally {
        // If the transaction is suspended, resume it.
        if (suspendedResourcesHolder != null) {
            tx.resume(suspendedResourcesHolder);
        }
    }
}
Also used : GlobalLockConfig(io.seata.core.model.GlobalLockConfig) TransactionException(io.seata.core.exception.TransactionException) Propagation(io.seata.tm.api.transaction.Propagation) SuspendedResourcesHolder(io.seata.tm.api.transaction.SuspendedResourcesHolder) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) TransactionInfo(io.seata.tm.api.transaction.TransactionInfo)

Example 30 with ShouldNeverHappenException

use of io.seata.common.exception.ShouldNeverHappenException in project seata by seata.

the class MysqlTableMetaCache method resultSetMetaToSchema.

private TableMeta resultSetMetaToSchema(ResultSetMetaData rsmd, DatabaseMetaData dbmd) throws SQLException {
    // always "" for mysql
    String schemaName = rsmd.getSchemaName(1);
    String catalogName = rsmd.getCatalogName(1);
    /*
         * use ResultSetMetaData to get the pure table name
         * can avoid the problem below
         *
         * select * from account_tbl
         * select * from account_TBL
         * select * from `account_tbl`
         * select * from account.account_tbl
         */
    String tableName = rsmd.getTableName(1);
    TableMeta tm = new TableMeta();
    tm.setTableName(tableName);
    try (ResultSet rsColumns = dbmd.getColumns(catalogName, schemaName, tableName, "%");
        ResultSet rsIndex = dbmd.getIndexInfo(catalogName, schemaName, tableName, false, true)) {
        while (rsColumns.next()) {
            ColumnMeta col = new ColumnMeta();
            col.setTableCat(rsColumns.getString("TABLE_CAT"));
            col.setTableSchemaName(rsColumns.getString("TABLE_SCHEM"));
            col.setTableName(rsColumns.getString("TABLE_NAME"));
            col.setColumnName(rsColumns.getString("COLUMN_NAME"));
            col.setDataType(rsColumns.getInt("DATA_TYPE"));
            col.setDataTypeName(rsColumns.getString("TYPE_NAME"));
            col.setColumnSize(rsColumns.getInt("COLUMN_SIZE"));
            col.setDecimalDigits(rsColumns.getInt("DECIMAL_DIGITS"));
            col.setNumPrecRadix(rsColumns.getInt("NUM_PREC_RADIX"));
            col.setNullAble(rsColumns.getInt("NULLABLE"));
            col.setRemarks(rsColumns.getString("REMARKS"));
            col.setColumnDef(rsColumns.getString("COLUMN_DEF"));
            col.setSqlDataType(rsColumns.getInt("SQL_DATA_TYPE"));
            col.setSqlDatetimeSub(rsColumns.getInt("SQL_DATETIME_SUB"));
            col.setCharOctetLength(rsColumns.getInt("CHAR_OCTET_LENGTH"));
            col.setOrdinalPosition(rsColumns.getInt("ORDINAL_POSITION"));
            col.setIsNullAble(rsColumns.getString("IS_NULLABLE"));
            col.setIsAutoincrement(rsColumns.getString("IS_AUTOINCREMENT"));
            tm.getAllColumns().put(col.getColumnName(), col);
        }
        while (rsIndex.next()) {
            String indexName = rsIndex.getString("INDEX_NAME");
            String colName = rsIndex.getString("COLUMN_NAME");
            ColumnMeta col = tm.getAllColumns().get(colName);
            if (tm.getAllIndexes().containsKey(indexName)) {
                IndexMeta index = tm.getAllIndexes().get(indexName);
                index.getValues().add(col);
            } else {
                IndexMeta index = new IndexMeta();
                index.setIndexName(indexName);
                index.setNonUnique(rsIndex.getBoolean("NON_UNIQUE"));
                index.setIndexQualifier(rsIndex.getString("INDEX_QUALIFIER"));
                index.setIndexName(rsIndex.getString("INDEX_NAME"));
                index.setType(rsIndex.getShort("TYPE"));
                index.setOrdinalPosition(rsIndex.getShort("ORDINAL_POSITION"));
                index.setAscOrDesc(rsIndex.getString("ASC_OR_DESC"));
                index.setCardinality(rsIndex.getInt("CARDINALITY"));
                index.getValues().add(col);
                if ("PRIMARY".equalsIgnoreCase(indexName)) {
                    index.setIndextype(IndexType.PRIMARY);
                } else if (!index.isNonUnique()) {
                    index.setIndextype(IndexType.UNIQUE);
                } else {
                    index.setIndextype(IndexType.NORMAL);
                }
                tm.getAllIndexes().put(indexName, index);
            }
        }
        if (tm.getAllIndexes().isEmpty()) {
            throw new ShouldNeverHappenException("Could not found any index in the table: " + tableName);
        }
    }
    return tm;
}
Also used : ColumnMeta(io.seata.rm.datasource.sql.struct.ColumnMeta) ResultSet(java.sql.ResultSet) ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) IndexMeta(io.seata.rm.datasource.sql.struct.IndexMeta) TableMeta(io.seata.rm.datasource.sql.struct.TableMeta)

Aggregations

ShouldNeverHappenException (io.seata.common.exception.ShouldNeverHappenException)40 TableRecords (io.seata.rm.datasource.sql.struct.TableRecords)11 Row (io.seata.rm.datasource.sql.struct.Row)9 ArrayList (java.util.ArrayList)9 List (java.util.List)8 TransactionException (io.seata.core.exception.TransactionException)7 SQLUndoLog (io.seata.rm.datasource.undo.SQLUndoLog)7 CollectionUtils (io.seata.common.util.CollectionUtils)6 ColumnUtils (io.seata.rm.datasource.ColumnUtils)6 Field (io.seata.rm.datasource.sql.struct.Field)6 AbstractUndoExecutor (io.seata.rm.datasource.undo.AbstractUndoExecutor)6 JdbcConstants (io.seata.sqlparser.util.JdbcConstants)6 Collectors (java.util.stream.Collectors)6 ColumnMeta (io.seata.rm.datasource.sql.struct.ColumnMeta)5 TableMeta (io.seata.rm.datasource.sql.struct.TableMeta)4 Method (java.lang.reflect.Method)4 ResultSet (java.sql.ResultSet)4 SqlGenerateUtils (io.seata.rm.datasource.SqlGenerateUtils)3 IndexMeta (io.seata.rm.datasource.sql.struct.IndexMeta)3 HashMap (java.util.HashMap)3