diff --git a/changes/en-us/2.0.0.md b/changes/en-us/2.0.0.md index 6f565947176..9596c8fcf63 100644 --- a/changes/en-us/2.0.0.md +++ b/changes/en-us/2.0.0.md @@ -152,6 +152,7 @@ The version is updated as follows: - [[#5951](https://github.com/seata/seata/pull/5951)] remove un support config in jdk17 - [[#5959](https://github.com/seata/seata/pull/5959)] modify code style and remove unused import - [[#6002](https://github.com/seata/seata/pull/6002)] remove fst serialization +- [[#6045](https://github.com/seata/seata/pull/6045)] optimize derivative product check base on mysql ### security: diff --git a/changes/zh-cn/2.0.0.md b/changes/zh-cn/2.0.0.md index ef63a7db76c..bd2b578be60 100644 --- a/changes/zh-cn/2.0.0.md +++ b/changes/zh-cn/2.0.0.md @@ -153,6 +153,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单 - [[#5951](https://github.com/seata/seata/pull/5951)] 删除在 jdk17 中不支持的配置项 - [[#5959](https://github.com/seata/seata/pull/5959)] 修正代码风格问题及去除无用的类引用 - [[#6002](https://github.com/seata/seata/pull/6002)] 移除fst序列化模块 +- [[#6045](https://github.com/seata/seata/pull/6045)] 优化MySQL衍生数据库判断逻辑 ### security: diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceProxy.java b/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceProxy.java index 48317a83516..6d930ea4009 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceProxy.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceProxy.java @@ -19,7 +19,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Statement; import javax.sql.DataSource; @@ -31,6 +30,7 @@ import io.seata.rm.datasource.sql.struct.TableMetaCacheFactory; import io.seata.rm.datasource.util.JdbcUtils; import io.seata.sqlparser.util.JdbcConstants; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,7 +55,16 @@ public class DataSourceProxy extends AbstractDataSourceProxy implements Resource private String userName; - private String version; + private String kernelVersion; + + private String productVersion; + + /** + * POLARDB-X 1.X -> TDDL + * POLARDB-X 2.X & MySQL 5.6 -> PXC + * POLARDB-X 2.X & MySQL 5.7 -> AliSQL-X + */ + private static final String[] POLARDB_X_PRODUCT_KEYWORD = {"TDDL","AliSQL-X","PXC"}; /** * Instantiates a new Data source proxy. @@ -89,9 +98,9 @@ private void init(DataSource dataSource, String resourceGroupId) { if (JdbcConstants.ORACLE.equals(dbType)) { userName = connection.getMetaData().getUserName(); } else if (JdbcConstants.MYSQL.equals(dbType)) { - getMySQLAdaptiveType(connection); + validMySQLVersion(connection); + checkDerivativeProduct(); } - version = selectDbVersion(connection); } catch (SQLException e) { throw new IllegalStateException("can not init dataSource", e); } @@ -107,17 +116,31 @@ private void init(DataSource dataSource, String resourceGroupId) { } /** - * get mysql adaptive type for PolarDB-X + * Define derivative product version for MySQL Kernel * - * @param connection db connection */ - private void getMySQLAdaptiveType(Connection connection) { - try (Statement statement = connection.createStatement()) { - statement.executeQuery("show rule"); + private void checkDerivativeProduct() { + if (!JdbcConstants.MYSQL.equals(dbType)) { + return; + } + // check for polardb-x + if (isPolardbXProduct()) { dbType = JdbcConstants.POLARDBX; - } catch (SQLException e) { - dbType = JdbcConstants.MYSQL; + return; + } + // check for other products base on mysql kernel + } + + private boolean isPolardbXProduct() { + if (StringUtils.isBlank(productVersion)) { + return false; + } + for (String keyword : POLARDB_X_PRODUCT_KEYWORD) { + if (productVersion.contains(keyword)) { + return true; + } } + return false; } /** @@ -335,27 +358,33 @@ public BranchType getBranchType() { return BranchType.AT; } - public String getVersion() { - return version; + public String getKernelVersion() { + return kernelVersion; } - private String selectDbVersion(Connection connection) { - if (JdbcConstants.MYSQL.equals(dbType) || JdbcConstants.POLARDBX.equals(dbType)) { - try (PreparedStatement preparedStatement = connection.prepareStatement("SELECT VERSION()"); - ResultSet versionResult = preparedStatement.executeQuery()) { - if (versionResult.next()) { - String version = versionResult.getString("VERSION()"); - if (version == null) { - return null; - } - int dashIdx = version.indexOf('-'); - // in mysql: 5.6.45, in polardb-x: 5.6.45-TDDL-xxx - return dashIdx > 0 ? version.substring(0, dashIdx) : version; + private void validMySQLVersion(Connection connection) { + if (!JdbcConstants.MYSQL.equals(dbType)) { + return; + } + try (PreparedStatement preparedStatement = connection.prepareStatement("SELECT VERSION()"); + ResultSet versionResult = preparedStatement.executeQuery()) { + if (versionResult.next()) { + String version = versionResult.getString("VERSION()"); + if (StringUtils.isBlank(version)) { + return; + } + int dashIdx = version.indexOf('-'); + // in mysql: 5.6.45, in polardb-x: 5.6.45-TDDL-xxx + if (dashIdx > 0) { + kernelVersion = version.substring(0, dashIdx); + productVersion = version.substring(dashIdx + 1); + } else { + kernelVersion = version; + productVersion = version; } - } catch (Exception e) { - LOGGER.error("get mysql version fail error: {}", e.getMessage()); } + } catch (Exception e) { + LOGGER.error("check mysql version fail error: {}", e.getMessage()); } - return ""; } } diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java index 50cac9fa611..e307bc4f371 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java @@ -310,6 +310,6 @@ private String buildGroupBy(List pkColumns,List allSelectColumns } private String getDbVersion() { - return statementProxy.getConnectionProxy().getDataSourceProxy().getVersion(); + return statementProxy.getConnectionProxy().getDataSourceProxy().getKernelVersion(); } }