diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index 2b586927185..ee15b98e0c0 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -81,6 +81,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6301](https://github.com/apache/incubator-seata/pull/6301)] upgrade console frontend dependencies and supported nodejs versions - [[#6301](https://github.com/apache/incubator-seata/pull/6312)] add saga related io.seata compatible api - [[#6313](https://github.com/apache/incubator-seata/pull/6313)] console display the version number +- [[#6330](https://github.com/apache/incubator-seata/pull/6330)] remove mariadb API - [[#6329](https://github.com/apache/incubator-seata/pull/6312)] add saga subcomponent-level io.seata compatible api - [[#6254](https://github.com/apache/incubator-seata/pull/6254)] optimize Hessian Serialize diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index c9711e2f207..22a26766a9f 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -79,6 +79,7 @@ - [[#6301](https://github.com/apache/incubator-seata/pull/6301)] 升级console前端依赖及支持的nodejs版本 - [[#6301](https://github.com/apache/incubator-seata/pull/6312)] 添加saga相关的io.seata兼容性API - [[#6313](https://github.com/apache/incubator-seata/pull/6313)] console展示版本号 +- [[#6330](https://github.com/apache/incubator-seata/pull/6330)] 去除 mariadb API - [[#6329](https://github.com/apache/incubator-seata/pull/6312)] 添加saga子组件的io.seata兼容性API - [[#6254](https://github.com/apache/incubator-seata/pull/6254)] 优化Hessian 序列化 diff --git a/rm-datasource/pom.xml b/rm-datasource/pom.xml index 5318ac15447..93f3c5a9e92 100644 --- a/rm-datasource/pom.xml +++ b/rm-datasource/pom.xml @@ -125,8 +125,7 @@ org.mariadb.jdbc mariadb-java-client - provided - true + test commons-logging diff --git a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/util/XAUtils.java b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/util/XAUtils.java index d1c8c12bef1..1d79407a144 100644 --- a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/util/XAUtils.java +++ b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/util/XAUtils.java @@ -20,15 +20,19 @@ import java.sql.Connection; import java.sql.Driver; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import javax.sql.XAConnection; import javax.transaction.xa.XAException; + import com.alibaba.druid.util.JdbcUtils; import com.alibaba.druid.util.MySqlUtils; import com.alibaba.druid.util.PGUtils; + import org.apache.seata.rm.BaseDataSourceResource; import org.apache.seata.sqlparser.util.JdbcConstants; -import org.mariadb.jdbc.MariaDbConnection; -import org.mariadb.jdbc.MariaXaConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,49 +48,101 @@ public static XAConnection createXAConnection(Connection physicalConn, BaseDataS return createXAConnection(physicalConn, dataSourceResource.getDriver(), dataSourceResource.getDbType()); } - public static XAConnection createXAConnection(Connection physicalConn, Driver driver, String dbType) throws SQLException { + public static XAConnection createXAConnection(Connection physicalConn, Driver driver, String dbType) + throws SQLException { if (JdbcConstants.MYSQL.equals(dbType)) { return MySqlUtils.createXAConnection(driver, physicalConn); } else { - switch (dbType) { - case JdbcConstants.ORACLE: - try { + try { + switch (dbType) { + case JdbcConstants.ORACLE: // https://github.com/alibaba/druid/issues/3707 // before Druid issue fixed, just make ORACLE XA connection in my way. // return OracleUtils.OracleXAConnection(physicalConn); String physicalConnClassName = physicalConn.getClass().getName(); if ("oracle.jdbc.driver.T4CConnection".equals(physicalConnClassName)) { - return createOracleXAConnection(physicalConn, "oracle.jdbc.driver.T4CXAConnection"); + return createXAConnection(physicalConn, "oracle.jdbc.driver.T4CXAConnection", dbType); } else { - return createOracleXAConnection(physicalConn, "oracle.jdbc.xa.client.OracleXAConnection"); + return createXAConnection(physicalConn, "oracle.jdbc.xa.client.OracleXAConnection", dbType); } - } catch (XAException xae) { - throw new SQLException("create xaConnection error", xae); - } - case JdbcConstants.MARIADB: - return new MariaXaConnection((MariaDbConnection)physicalConn); - case JdbcConstants.POSTGRESQL: - return PGUtils.createXAConnection(physicalConn); - default: - throw new SQLException("xa not support dbType: " + dbType); + case JdbcConstants.MARIADB: + return createXAConnection(physicalConn, "org.mariadb.jdbc.MariaXaConnection", dbType); + case JdbcConstants.POSTGRESQL: + return PGUtils.createXAConnection(physicalConn); + default: + throw new SQLException("xa not support dbType: " + dbType); + } + } catch (Exception xae) { + throw new SQLException("create xaConnection error", xae); } } } - private static XAConnection createOracleXAConnection(Connection physicalConnection, String xaConnectionClassName) throws XAException, SQLException { + private static XAConnection createXAConnection(Connection physicalConnection, String xaConnectionClassName, + String dbType) throws XAException, SQLException { try { Class xaConnectionClass = Class.forName(xaConnectionClassName); - Constructor constructor = xaConnectionClass.getConstructor(Connection.class); + Constructor constructor = getConstructorByDBType(xaConnectionClass, dbType); + if (constructor == null) { + throw new SQLException("xa not support dbType: " + dbType); + } constructor.setAccessible(true); - return constructor.newInstance(physicalConnection); + List params = getInitargsByDBType(dbType, physicalConnection); + return constructor.newInstance(params.toArray(new Object[0])); } catch (Exception e) { - LOGGER.warn("Failed to create Oracle XA Connection " + xaConnectionClassName + " on " + physicalConnection); + LOGGER.warn("Failed to create XA Connection " + xaConnectionClassName + " on " + physicalConnection); if (e instanceof XAException) { - throw (XAException) e; + throw (XAException)e; } else { throw new SQLException(e); } } } + + private static Constructor getConstructorByDBType(Class xaConnectionClass, String dbType) throws SQLException { + try { + switch (dbType) { + case JdbcConstants.ORACLE: + return xaConnectionClass.getConstructor(Connection.class); + case JdbcConstants.MARIADB: + //MariaXaConnection(MariaDbConnection connection) + Class mariaXaConnectionClass = Class.forName("org.mariadb.jdbc.MariaDbConnection"); + return xaConnectionClass.getConstructor(mariaXaConnectionClass); + default: + throw new SQLException("xa reflect not support dbType: " + dbType); + } + } catch (Exception e) { + throw new SQLException(e); + } + } + + private static List getInitargsByDBType(String dbType, Object... params) throws SQLException { + List result = new ArrayList<>(); + if (params.length == 0) { + return null; + } + if (!(params[0] instanceof Connection)) { + throw new SQLException("not support params: " + Arrays.toString(params)); + } + + try { + switch (dbType) { + case JdbcConstants.ORACLE: + result.add(params[0]); + return result; + case JdbcConstants.MARIADB: + Class mariaDbConnectionClass = Class.forName("org.mariadb.jdbc.MariaDbConnection"); + if (mariaDbConnectionClass.isInstance(params[0])) { + Object mariaDbConnectionInstance = mariaDbConnectionClass.cast(params[0]); + result.add(mariaDbConnectionInstance); + return result; + } + default: + throw new SQLException("xa reflect not support dbType: " + dbType); + } + } catch (Exception e) { + throw new SQLException(e); + } + } } diff --git a/rm-datasource/src/test/java/org/apache/seata/rm/xa/DataSourceProxyXATest.java b/rm-datasource/src/test/java/org/apache/seata/rm/xa/DataSourceProxyXATest.java index 6f9f0ed3717..d72210e5e5a 100644 --- a/rm-datasource/src/test/java/org/apache/seata/rm/xa/DataSourceProxyXATest.java +++ b/rm-datasource/src/test/java/org/apache/seata/rm/xa/DataSourceProxyXATest.java @@ -16,7 +16,17 @@ */ package org.apache.seata.rm.xa; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.Driver; +import java.sql.SQLException; + +import javax.sql.DataSource; +import javax.sql.PooledConnection; +import javax.sql.XAConnection; + import com.alibaba.druid.pool.DruidDataSource; + import com.mysql.jdbc.JDBC4MySQLConnection; import com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper; import org.apache.seata.core.context.RootContext; @@ -26,22 +36,12 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.mariadb.jdbc.MariaDbConnection; import org.mockito.Mockito; -import javax.sql.DataSource; -import javax.sql.PooledConnection; -import javax.sql.XAConnection; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.Driver; -import java.sql.SQLException; - import static org.mockito.ArgumentMatchers.any; /** * Tests for DataSourceProxyXA - * */ public class DataSourceProxyXATest { @@ -91,10 +91,11 @@ public void testGetConnection() throws SQLException { } @Test - public void testGetMariaXaConnection() throws SQLException { + public void testGetMariaXaConnection() throws SQLException, ClassNotFoundException { // Mock Driver driver = Mockito.mock(Driver.class); - MariaDbConnection connection = Mockito.mock(MariaDbConnection.class); + Class clazz = Class.forName("org.mariadb.jdbc.MariaDbConnection"); + Connection connection = (Connection)(Mockito.mock(clazz)); Mockito.when(connection.getAutoCommit()).thenReturn(true); DatabaseMetaData metaData = Mockito.mock(DatabaseMetaData.class); Mockito.when(metaData.getURL()).thenReturn("jdbc:mariadb:xxx"); @@ -120,12 +121,12 @@ public void testGetMariaXaConnection() throws SQLException { XAConnection xaConnection = connectionProxyXA.getWrappedXAConnection(); Connection connectionInXA = xaConnection.getConnection(); - Assertions.assertTrue(connectionInXA instanceof MariaDbConnection); + Assertions.assertEquals("org.mariadb.jdbc.MariaDbConnection", connectionInXA.getClass().getName()); tearDown(); } @AfterAll - public static void tearDown(){ + public static void tearDown() { RootContext.unbind(); } }