diff --git a/pom.xml b/pom.xml
index a44fd6a611..b88a36e085 100644
--- a/pom.xml
+++ b/pom.xml
@@ -412,7 +412,7 @@
com.h2database
h2
- 1.3.167
+ 1.3.168
test
diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
index 7b6adf3a98..c592732e03 100644
--- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
+++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
@@ -375,9 +375,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
this.dbType = JdbcUtils.getDbType(jdbcUrl, driverClass.getClass().getName());
}
- if ("oracle".equals(this.dbType)) {
- initOracle();
- }
+ initCheck();
initExceptionSorter();
initValidConnectionChecker();
@@ -510,16 +508,18 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
LOG.error(errorMessage + "validationQuery not set");
}
- protected void initOracle() throws SQLException {
- isOracle = true;
+ protected void initCheck() throws SQLException {
+ if (JdbcUtils.ORACLE.equals(this.dbType)) {
+ isOracle = true;
- if (driver.getMajorVersion() < 10) {
- throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "."
- + driver.getMinorVersion());
- }
+ if (driver.getMajorVersion() < 10) {
+ throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "."
+ + driver.getMinorVersion());
+ }
- if (driver.getMajorVersion() == 10 && isUseOracleImplicitCache()) {
- this.getConnectProperties().setProperty("oracle.jdbc.FreeMemoryOnEnterImplicitCache", "true");
+ if (driver.getMajorVersion() == 10 && isUseOracleImplicitCache()) {
+ this.getConnectProperties().setProperty("oracle.jdbc.FreeMemoryOnEnterImplicitCache", "true");
+ }
}
}
diff --git a/src/main/java/com/alibaba/druid/pool/xa/DruidAXDataSource.java b/src/main/java/com/alibaba/druid/pool/xa/DruidXADataSource.java
similarity index 57%
rename from src/main/java/com/alibaba/druid/pool/xa/DruidAXDataSource.java
rename to src/main/java/com/alibaba/druid/pool/xa/DruidXADataSource.java
index 51b166c535..4c03b49559 100644
--- a/src/main/java/com/alibaba/druid/pool/xa/DruidAXDataSource.java
+++ b/src/main/java/com/alibaba/druid/pool/xa/DruidXADataSource.java
@@ -11,40 +11,62 @@ import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
+import com.alibaba.druid.util.H2Utils;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.MySqlUtils;
import com.alibaba.druid.util.OracleUtils;
import com.alibaba.druid.util.PGUtils;
-public class DruidAXDataSource extends DruidDataSource implements XADataSource {
+public class DruidXADataSource extends DruidDataSource implements XADataSource {
- private final static Log LOG = LogFactory.getLog(DruidAXDataSource.class);
+ private final static Log LOG = LogFactory.getLog(DruidXADataSource.class);
private static final long serialVersionUID = 1L;
+ private Object h2Factory = null;
+
@Override
public XAConnection getXAConnection() throws SQLException {
DruidPooledConnection conn = this.getConnection();
Connection physicalConn = conn.unwrap(Connection.class);
- XAConnection rawXAConnection;
+ XAConnection rawXAConnection = createPhysicalXAConnetion(physicalConn);
+
+ return new DruidPooledXAConnection(conn, rawXAConnection);
+ }
+
+ protected void initCheck() throws SQLException {
+ super.initCheck();
+
+ if (JdbcUtils.H2.equals(this.dbType)) {
+ h2Factory = H2Utils.createJdbcDataSourceFactory();
+ }
+ }
+
+ private XAConnection createPhysicalXAConnetion(Connection physicalConn) throws SQLException {
if (JdbcUtils.ORACLE.equals(dbType)) {
try {
- rawXAConnection = OracleUtils.OracleXAConnection(physicalConn);
+ return OracleUtils.OracleXAConnection(physicalConn);
} catch (XAException xae) {
LOG.error("create xaConnection error", xae);
return null;
}
- } else if (JdbcUtils.MYSQL.equals(dbType)) {
- rawXAConnection = MySqlUtils.createXAConnection(physicalConn);
- } else if (JdbcUtils.POSTGRESQL.equals(dbType)) {
- rawXAConnection = PGUtils.createXAConnection(physicalConn);
- } else {
- throw new SQLException("xa not support dbType : " + this.dbType);
}
- return new DruidPooledXAConnection(conn, rawXAConnection);
+ if (JdbcUtils.MYSQL.equals(dbType)) {
+ return MySqlUtils.createXAConnection(physicalConn);
+ }
+
+ if (JdbcUtils.POSTGRESQL.equals(dbType)) {
+ return PGUtils.createXAConnection(physicalConn);
+ }
+
+ if (JdbcUtils.H2.equals(dbType)) {
+ return H2Utils.createXAConnection(h2Factory, physicalConn);
+ }
+
+ throw new SQLException("xa not support dbType : " + this.dbType);
}
@Override
diff --git a/src/main/java/com/alibaba/druid/util/H2Utils.java b/src/main/java/com/alibaba/druid/util/H2Utils.java
new file mode 100644
index 0000000000..35d9af3659
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/util/H2Utils.java
@@ -0,0 +1,52 @@
+package com.alibaba.druid.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.sql.XAConnection;
+
+import org.h2.jdbc.JdbcConnection;
+import org.h2.jdbcx.JdbcDataSourceFactory;
+import org.h2.jdbcx.JdbcXAConnection;
+import org.h2.message.TraceObject;
+
+public class H2Utils {
+
+ private static volatile Constructor constructor;
+
+ private static volatile Method method;
+
+ public static final int XA_DATA_SOURCE = 13;
+
+ public static Object createJdbcDataSourceFactory() {
+ return new JdbcDataSourceFactory();
+ }
+
+ public static XAConnection createXAConnection(Object factory, Connection physicalConn) throws SQLException {
+
+ try {
+ if (constructor == null) {
+ constructor = JdbcXAConnection.class.getConstructor(JdbcDataSourceFactory.class, int.class,
+ JdbcConnection.class);
+ constructor.setAccessible(true);
+ }
+
+ int id = getNextId(XA_DATA_SOURCE);
+
+ return constructor.newInstance(factory, id, physicalConn);
+ } catch (Exception e) {
+ throw new SQLException("createXAConnection error", e);
+ }
+ }
+
+ public static int getNextId(int type) throws Exception {
+ if (method == null) {
+ method = TraceObject.class.getMethod("getNextId", int.class);
+ method.setAccessible(true);
+ }
+
+ return (Integer) method.invoke(null, type);
+ }
+}
diff --git a/src/main/java/com/alibaba/druid/util/MySqlUtils.java b/src/main/java/com/alibaba/druid/util/MySqlUtils.java
index 7f0e97ea99..ca58bc6da6 100644
--- a/src/main/java/com/alibaba/druid/util/MySqlUtils.java
+++ b/src/main/java/com/alibaba/druid/util/MySqlUtils.java
@@ -3,11 +3,13 @@ package com.alibaba.druid.util;
import java.sql.Connection;
import java.sql.SQLException;
+import javax.sql.XAConnection;
+
import com.mysql.jdbc.jdbc2.optional.MysqlXAConnection;
public class MySqlUtils {
- public static MysqlXAConnection createXAConnection(Connection physicalConn) throws SQLException {
+ public static XAConnection createXAConnection(Connection physicalConn) throws SQLException {
return new MysqlXAConnection((com.mysql.jdbc.ConnectionImpl) physicalConn, false);
}
}
diff --git a/src/main/java/com/alibaba/druid/util/OracleUtils.java b/src/main/java/com/alibaba/druid/util/OracleUtils.java
index 139f5e949c..3ef1bbfd2f 100644
--- a/src/main/java/com/alibaba/druid/util/OracleUtils.java
+++ b/src/main/java/com/alibaba/druid/util/OracleUtils.java
@@ -5,6 +5,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import javax.sql.XAConnection;
import javax.transaction.xa.XAException;
import oracle.jdbc.OracleConnection;
@@ -19,7 +20,7 @@ import com.alibaba.druid.pool.DruidPooledPreparedStatement;
public class OracleUtils {
- public static OracleXAConnection OracleXAConnection(Connection oracleConnection) throws XAException {
+ public static XAConnection OracleXAConnection(Connection oracleConnection) throws XAException {
return new OracleXAConnection(oracleConnection);
}
diff --git a/src/main/java/com/alibaba/druid/util/PGUtils.java b/src/main/java/com/alibaba/druid/util/PGUtils.java
index 52ba89b66a..b9f7e71c89 100644
--- a/src/main/java/com/alibaba/druid/util/PGUtils.java
+++ b/src/main/java/com/alibaba/druid/util/PGUtils.java
@@ -3,12 +3,14 @@ package com.alibaba.druid.util;
import java.sql.Connection;
import java.sql.SQLException;
+import javax.sql.XAConnection;
+
import org.postgresql.core.BaseConnection;
import org.postgresql.xa.PGXAConnection;
public class PGUtils {
- public static PGXAConnection createXAConnection(Connection physicalConn) throws SQLException {
+ public static XAConnection createXAConnection(Connection physicalConn) throws SQLException {
return new PGXAConnection((BaseConnection) physicalConn);
}
}