mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
support OceanBase ExceptionSorter
Signed-off-by: hongwei yi hongweiyi@hotmail.com
This commit is contained in:
@@ -67,18 +67,7 @@ import com.alibaba.druid.filter.Filter;
|
||||
import com.alibaba.druid.filter.FilterChainImpl;
|
||||
import com.alibaba.druid.mock.MockDriver;
|
||||
import com.alibaba.druid.pool.DruidPooledPreparedStatement.PreparedStatementKey;
|
||||
import com.alibaba.druid.pool.vendor.DB2ExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.InformixExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.MSSQLValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.vendor.MockExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.MySqlExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.vendor.NullExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.OracleExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.OracleValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.vendor.PGExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.PGValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.vendor.SybaseExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.*;
|
||||
import com.alibaba.druid.proxy.DruidDriver;
|
||||
import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig;
|
||||
import com.alibaba.druid.proxy.jdbc.TransactionInfo;
|
||||
@@ -1346,6 +1335,12 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
} else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)
|
||||
|| realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) {
|
||||
this.exceptionSorter = new OracleExceptionSorter();
|
||||
} else if (realDriverClassName.equals(JdbcConstants.OCEANBASE_DRIVER)) {
|
||||
if (JdbcUtils.OCEANBASE_ORACLE.equalsIgnoreCase(dbType)) {
|
||||
this.exceptionSorter = new OceanBaseOracleExceptionSorter();
|
||||
} else {
|
||||
this.exceptionSorter = new MySqlExceptionSorter();
|
||||
}
|
||||
} else if (realDriverClassName.equals("com.informix.jdbc.IfxDriver")) {
|
||||
this.exceptionSorter = new InformixExceptionSorter();
|
||||
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
package com.alibaba.druid.pool.vendor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLRecoverableException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.druid.pool.ExceptionSorter;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
|
||||
public class OceanBaseOracleExceptionSorter extends OracleExceptionSorter {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(OracleExceptionSorter.class);
|
||||
private static final long serialVersionUID = -9146226891418913174L;
|
||||
private Set<Integer> fatalErrorCodes = new HashSet<Integer>();
|
||||
|
||||
public OceanBaseOracleExceptionSorter() {
|
||||
configFromProperties(System.getProperties());
|
||||
}
|
||||
|
||||
public void configFromProperties(Properties properties) {
|
||||
String property = properties.getProperty("druid.oracle.fatalErrorCodes");
|
||||
if (property != null) {
|
||||
String[] items = property.split("\\,");
|
||||
for (String item : items) {
|
||||
if (item != null && item.length() > 0) {
|
||||
try {
|
||||
int code = Integer.parseInt(item);
|
||||
fatalErrorCodes.add(code);
|
||||
} catch (NumberFormatException e) {
|
||||
LOG.error("parse druid.oracle.fatalErrorCodes error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Integer> getFatalErrorCodes() {
|
||||
return fatalErrorCodes;
|
||||
}
|
||||
|
||||
public void setFatalErrorCodes(Set<Integer> fatalErrorCodes) {
|
||||
this.fatalErrorCodes = fatalErrorCodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExceptionFatal(SQLException e) {
|
||||
if (e instanceof SQLRecoverableException) {
|
||||
return true;
|
||||
}
|
||||
final String sqlState = e.getSQLState();
|
||||
final int error_code = Math.abs(e.getErrorCode()); // I can't remember if the errors are negative or positive.
|
||||
if (sqlState != null && sqlState.startsWith("08")) {
|
||||
return true;
|
||||
}
|
||||
switch (error_code) {
|
||||
case 28: // your session has been killed
|
||||
case 600: // Internal oracle error
|
||||
case 1012: // not logged on
|
||||
case 1014: // Oracle shutdown in progress
|
||||
case 1033: // Oracle initialization or shutdown in progress
|
||||
case 1034: // Oracle not available
|
||||
case 1035: // ORACLE only available to users with RESTRICTED SESSION privilege
|
||||
case 1089: // immediate shutdown in progress - no operations are permitted
|
||||
case 1090: // shutdown in progress - connection is not permitted
|
||||
case 1092: // ORACLE instance terminated. Disconnection forced
|
||||
case 1094: // ALTER DATABASE CLOSE in progress. Connections not permitted
|
||||
case 2396: // exceeded maximum idle time, please connect again
|
||||
case 3106: // fatal two-task communication protocol error
|
||||
case 3111: // break received on communication channel
|
||||
case 3113: // end-of-file on communication channel
|
||||
case 3114: // not connected to ORACLE
|
||||
case 3134: // Connections to this server version are no longer supported.
|
||||
case 3135: // connection lost contact
|
||||
case 3136: // inbound connection timed out
|
||||
case 3138: // Connection terminated due to security policy violation
|
||||
case 3142: // Connection was lost for the specified session and serial number. This is either due to session
|
||||
// being killed or network problems.
|
||||
case 3143: // Connection was lost for the specified process ID and thread ID. This is either due to session
|
||||
// being killed or network problems.
|
||||
case 3144: // Connection was lost for the specified process ID. This is either due to session being killed
|
||||
// or network problems.
|
||||
case 3145: // I/O streaming direction error
|
||||
case 3149: // Invalid Oracle error code, Cause: An invalid Oracle error code was received by the server.
|
||||
case 6801: // TLI Driver: listen for SPX server reconnect failed
|
||||
case 6802: // TLI Driver: could not open the /etc/netware/yellowpages file
|
||||
case 6805: // TLI Driver: could not send datagram SAP packet for SPX
|
||||
case 9918: // Unable to get user privileges from SQL*Net
|
||||
case 9920: // Unable to get sensitivity label from connection
|
||||
case 9921: // Unable to get information label from connection
|
||||
// TTC(Two-Task Common) ERROR CODE
|
||||
case 17001: // Internal Error
|
||||
case 17002: // Io exception
|
||||
case 17008: // Closed Connection
|
||||
case 17009: // Closed Statement
|
||||
case 17024: // No data read
|
||||
case 17089: // internal error
|
||||
case 17409: // invalid buffer length
|
||||
case 17401: // Protocol violation
|
||||
case 17410: // No more data to read from socket
|
||||
case 17416: // FATAl
|
||||
case 17438: // Internal - Unexpected value
|
||||
case 17442: // Refcursor value is invalid
|
||||
case 25407: // connection terminated
|
||||
case 25408: // can not safely replay call
|
||||
case 25409: // failover happened during the network operation,cannot continue
|
||||
case 25425: // connection lost during rollback
|
||||
case 29276: // transfer timeout
|
||||
case 30676: // socket read or write failed
|
||||
return true;
|
||||
default:
|
||||
if (error_code >= 12100 && error_code <= 12299) { // TNS issues
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
final String error_text = (e.getMessage()).toUpperCase();
|
||||
// Exclude oracle user defined error codes (20000 through 20999) from consideration when looking for
|
||||
// certain strings.
|
||||
if ((error_code < 20000 || error_code >= 21000)) {
|
||||
if ((error_text.contains("SOCKET")) // for control socket error
|
||||
|| (error_text.contains("套接字")) // for control socket error
|
||||
|| (error_text.contains("CONNECTION HAS ALREADY BEEN CLOSED")) //
|
||||
|| (error_text.contains("BROKEN PIPE")) //
|
||||
|| (error_text.contains("管道已结束")) //
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (error_text.indexOf("COMMUNICATIONS LINK FAILURE") > -1
|
||||
|| error_text.indexOf("COULD NOT CREATE CONNECTION") > -1
|
||||
|| error_text.indexOf("ACCESS DENIED FOR USER") > -1
|
||||
|| error_text.indexOf("NO DATASOURCE") > -1
|
||||
|| error_text.indexOf("NO ALIVE DATASOURCE") > -1) {// errorCode忽略并且异常信息为连接出错
|
||||
return true;
|
||||
}
|
||||
|
||||
return fatalErrorCodes.contains(error_code);
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package com.alibaba.druid.bvt.pool.exception;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.pool.DruidPooledConnection;
|
||||
import com.alibaba.druid.pool.vendor.OceanBaseOracleExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.OracleExceptionSorter;
|
||||
import com.alibaba.druid.stat.JdbcStatManager;
|
||||
import com.alibaba.druid.test.util.OracleMockDriver;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class OceanBaseOracleExceptionSorterTest extends TestCase {
|
||||
|
||||
private DruidDataSource dataSource;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
Assert.assertEquals(0, JdbcStatManager.getInstance().getSqlList().size());
|
||||
|
||||
dataSource = new DruidDataSource();
|
||||
|
||||
dataSource.setExceptionSorter(new OceanBaseOracleExceptionSorter());
|
||||
|
||||
dataSource.setDriver(new OracleMockDriver());
|
||||
dataSource.setUrl("jdbc:mock:xxx");
|
||||
dataSource.setPoolPreparedStatements(true);
|
||||
dataSource.setMaxOpenPreparedStatements(100);
|
||||
dataSource.setFilters("log4j");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
JdbcUtils.close(dataSource);
|
||||
}
|
||||
|
||||
public void test_connect() throws Exception {
|
||||
String sql = "SELECT 1";
|
||||
{
|
||||
DruidPooledConnection conn = dataSource.getConnection();
|
||||
|
||||
PreparedStatement pstmt = conn.prepareStatement(sql);
|
||||
pstmt.execute();
|
||||
pstmt.close();
|
||||
conn.close();
|
||||
}
|
||||
|
||||
DruidPooledConnection conn = dataSource.getConnection();
|
||||
PreparedStatement pstmt = conn.prepareStatement(sql);
|
||||
pstmt.setFetchSize(1000);
|
||||
|
||||
SQLException exception = new SQLException("xx", "xxx", 28);
|
||||
boolean fatal = false;
|
||||
try {
|
||||
conn.handleException(exception);
|
||||
} catch (SQLException ex) {
|
||||
fatal = true;
|
||||
}
|
||||
Assert.assertTrue(fatal);
|
||||
|
||||
pstmt.close();
|
||||
|
||||
SQLException commitError = null;
|
||||
try {
|
||||
conn.commit();
|
||||
} catch (SQLException ex) {
|
||||
commitError = ex;
|
||||
}
|
||||
|
||||
Assert.assertNotNull(commitError);
|
||||
Assert.assertSame(exception, commitError.getCause());
|
||||
|
||||
conn.close();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user