seata1.5.2适配DM8

  1. springboot依赖
 <!--seata依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <!--排除低版本seata依赖-->
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-all</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--添加⾼版本seata依赖-->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.5.2</version>
        </dependency>
  1. 新建类 MyDbTypeParser

    
    import io.seata.common.loader.LoadLevel; import
    io.seata.sqlparser.util.DbTypeParser;
    
    @LoadLevel(name = "druid", order = 1) public class MyDbTypeParser
    implements DbTypeParser {
    
    	public MyDbTypeParser() { 	}
    
    	@Override 	public String parseFromJdbcUrl(String jdbcUrl) {
    		return "mysql"; 	} }
    
    
    1. 在resource目录下创建配置文件 新建文件夹 /META-INF/services 新建文件io.seata.sqlparser.util.DbTypeParser
    io.seata.sqlparser.druid.MyDbTypeParser 
    
    1. 拷贝seata-all.jar 下io.seata.rm.datasource.sql.struct.cache.MysqlTableMetaCache
      修改其中一段内容
    package io.seata.rm.datasource.sql.struct.cache;
    
    import java.sql.Connection; 
    import java.sql.DatabaseMetaData; 
    import java.sql.ResultSet; 
    import java.sql.ResultSetMetaData; 
    import java.sql.SQLException; 
    import java.sql.Statement;
    import io.seata.common.exception.NotSupportYetException; 
    import io.seata.common.exception.ShouldNeverHappenException; 
    import io.seata.common.loader.LoadLevel; 
    import io.seata.rm.datasource.ColumnUtils; 
    import io.seata.rm.datasource.sql.struct.ColumnMeta; 
    import io.seata.rm.datasource.sql.struct.IndexMeta; 
    import io.seata.rm.datasource.sql.struct.IndexType; 
    import io.seata.rm.datasource.sql.struct.TableMeta; 
    import io.seata.sqlparser.util.JdbcConstants; 
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**  * The type Table meta cache.  *  * @author sharajava  */
    @LoadLevel(name = JdbcConstants.MYSQL, order = 1) public class
    MysqlTableMetaCache extends AbstractTableMetaCache {
    
    private static final Logger LOGGER =
    LoggerFactory.getLogger(MysqlTableMetaCache.class);
    
    @Override protected String getCacheKey(Connection connection, String
    tableName, String resourceId) {
        StringBuilder cacheKey = new StringBuilder(resourceId);
        cacheKey.append(".");
        //remove single quote and separate it to catalogName and tableName
        String[] tableNameWithCatalog = tableName.replace("`", "").split("\\.");
        String defaultTableName = tableNameWithCatalog.length > 1 ? tableNameWithCatalog[1] : tableNameWithCatalog[0];
    
        DatabaseMetaData databaseMetaData = null;
        try {
            databaseMetaData = connection.getMetaData();
        } catch (SQLException e) {
            LOGGER.error("Could not get connection, use default cache key {}", e.getMessage(), e);
            return cacheKey.append(defaultTableName).toString();
        }
    
        try {
            //prevent duplicated cache key
            if (databaseMetaData.supportsMixedCaseIdentifiers()) {
                cacheKey.append(defaultTableName);
            } else {
                cacheKey.append(defaultTableName.toLowerCase());
            }
        } catch (SQLException e) {
            LOGGER.error("Could not get supportsMixedCaseIdentifiers in connection metadata, use default cache key {}", e.getMessage(), e);
            return cacheKey.append(defaultTableName).toString();
        }
    
        return cacheKey.toString(); }
    
    @Override protected TableMeta fetchSchema(Connection connection,
    String tableName) throws SQLException {
        String sql = "SELECT * FROM " + ColumnUtils.addEscape(tableName, JdbcConstants.MYSQL) + " LIMIT 1";
        try (Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery(sql)) {
            return resultSetMetaToSchema(rs.getMetaData(), connection.getMetaData());
        } catch (SQLException sqlEx) {
            throw sqlEx;
        } catch (Exception e) {
            throw new SQLException(String.format("Failed to fetch schema of %s", tableName), e);
        } }
    
    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);
    
        /*
         * here has two different type to get the data
         * make sure the table name was right
         * 1. show full columns from xxx from xxx(normal)
         * 2. select xxx from xxx where catalog_name like ? and table_name like ?(informationSchema=true)
         */
    
        try (ResultSet rsColumns = dbmd.getColumns(catalogName, schemaName, tableName, "%");
             ResultSet rsIndex = dbmd.getIndexInfo(catalogName, schemaName, tableName, false, true);
             ResultSet onUpdateColumns = dbmd.getVersionColumns(catalogName, schemaName, tableName)) {
            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"));
    
                if (tm.getAllColumns().containsKey(col.getColumnName())) {
                    throw new NotSupportYetException("Not support the table has the same column name with different case yet");
                }
                tm.getAllColumns().put(col.getColumnName(), col);
            }
    
            while (onUpdateColumns.next()) {
                tm.getAllColumns().get(onUpdateColumns.getString("COLUMN_NAME")).setOnUpdate(true);
            }
    
            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);
                    //添加内容 || (indexName!=null && indexName.contains("INDEX")) dm的主键索引是INDEX+数字
                    if ("PRIMARY".equalsIgnoreCase(indexName)|| (indexName!=null && indexName.contains("INDEX"))) {
                        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; } }
    
    
    1. 修改dm8的dm.ini context是dm的关键字需要屏蔽 修改后需要重启数据库
    EXCLUDE_RESERVED_WORDS = CONTEXT
    

    也可以在dm_svc.conf配置文件中KEYWORDS配置项进行屏蔽 修改后需要重启数据库

在这里插入图片描述

KEY_WORDS=(CONTEXT)
 dm_svc.conf DM安装时生产的一个
  1. seata配置加上
seata.client.rm.sql-parser-type=druid
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值