I have an application where user can choose any type and version of database(relational) provide URL, username, password and create datasource, connect to database, then run SELECT queries. To connect database I am using HikariCp for my connection pool(before I used DBCP2 as connection timeout didn't work I changed to HikariCp). Here is my configuration
HikariConfig config = new HikariConfig();
config.setDriverClassName(StringUtils.trimToEmpty(driver));
config.setJdbcUrl(StringUtils.trimToEmpty(url));
config.setUsername(username);
config.setPassword(password);
config.setMaximumPoolSize(POOL_MAX_ACTIVE);
config.setMinimumIdle(POOL_INITIAL_SIZE);
config.setConnectionTestQuery(validationQuery);
config.setConnectionTimeout(TimeUnit.SECONDS.toMillis(jdbcTimeout));
HikariDataSource dataSource = new HikariDataSource(config);
Connection connection = dataSource.getConnection();
When I am trying to connect MYsql database I am getting the following error:
HikariPool-8 - Starting...
2019-04-10 18:45:49 WARN com.zaxxer.hikari.pool.PoolBase:472 - ReqId:60a79ef60413424e96a4fa73010fc861 - HikariPool-8 - Default transaction isolation level detection failed ((conn=14) Unknown system variable 'tx_isolation').
2019-04-10 18:45:49 ERROR com.zaxxer.hikari.pool.HikariPool:574 - ReqId:60a79ef60413424e96a4fa73010fc861 - HikariPool-8 - Exception during pool initialization.
java.sql.SQLException: (conn=14) Unknown system variable 'tx_isolation'
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:198)
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:110)
What is wrong in the configuration? with DBCP2 it works fine
I am using mariadb-java-client, version: '2.2.1' driver to connect to Mysql database.
Related
I am calling a web service and after frequently I am getting the below exception, how do I resolve it
com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset by
peer: socket write error\r\n\tat
com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1745)\r\n\tat
com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1732)\r\n\tat
com.microsoft.sqlserver.jdbc.TDSChannel.write(IOBuffer.java:1842)\r\n\tat
com.microsoft.sqlserver.jdbc.TDSWriter.flush(IOBuffer.java:4161)\r\n\tat
com.microsoft.sqlserver.jdbc.TDSWriter.writePacket(IOBuffer.java:4062)\r\n\tat
com.microsoft.sqlserver.jdbc.TDSWriter.endMessage(IOBuffer.java:3107)\r\n\tat
com.microsoft.sqlserver.jdbc.TDSCommand.startResponse(IOBuffer.java:6700)\r\n\tat
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:424)\r\n\tat
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:372)\r\n\tat
com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:6276)\r\n\tat
com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1793)\r\n\tat
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:184)\r\n\tat
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:159)\r\n\tat
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:315)\r\n\tat
org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)\r\n\tat
org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate
I am using Apache Commons BasicDataSource for connection pooling, and below is the code for the same
ds = new BasicDataSource();
ds.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
ds.setUsername(username);
ds.setPassword(password);
ds.setUrl(database_url);
// the settings below are optional -- dbcp can work with defaults
ds.setMinIdle(10);
ds.setMaxIdle(50);
ds.setMaxActive(100);
ds.setInitialSize(10);
I have a grails2 based application which is using tomcat jdbc pool, recently I have been getting into problem where all the connections in the pool get used up and I start getting:-
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.apache.tomcat.jdbc.pool.PoolExhaustedException: [http-nio-8443-exec-38] Timeout: Pool empty. Unable to fetch a connection in 10 seconds, none available[size:100; busy:100; idle:0; lastwait:10000].; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.apache.tomcat.jdbc.pool.PoolExhaustedException: [http-nio-8443-exec-38] Timeout: Pool empty. Unable to fetch a connection in 10 seconds, none available[size:100; busy:100; idle:0; lastwait:10000].
I have a few query that requires heavy join and some stored proc that executes for about 2 - 3 minutes, for it i am manually get the connection from the datasource bean :-
currentConnection = dataSource.connection
sqlInstance = new Sql(currentConnection)
sqlInstance.execute(query)
sqlInstance.close()
I've logged the total active connection in stdout and i see that the no. of active connection keeps on rising and rising and it never drops, it then gets to 100 which is the total active connection allowed and then i start getting issue of poolexhaustauion, can anyone give me an idea, what i might be missing or where the connection might be leaking. here is my connection detail :-
dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
url="jdbc:mysql://something:3306/something?zeroDateTimeBehavior=convertToNull&autoReconnect=true&relaxAutoCommit=true"
username="#####"
password='#$#$$$$$$$'
dbCreate = "update"
properties {
initialSize=5
maxActive=100
minIdle=5
maxIdle=25
maxWait = 10000
maxAge = 10 * 60000
timeBetweenEvictionRunsMillis=5000
minEvictableIdleTimeMillis=60000
validationQuery="SELECT 1"
validationInterval=15000
testWhileIdle=true
testOnBorrow=true
testOnReturn=true
removeAbandoned=true
removeAbandonedTimeout=400
logAbandoned=true
jdbcInterceptors = "ConnectionState"
defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
}
}
I've got a spring application, one of it's functions is to be able to take any piece of SQL and run it, a poller polls a folder for a trigger file containing the location of a SQL file, the application then reads the SQL file and places contents into the 'sqlquery' message header.
Problem we seem to have is that exceptions aren't being thrown when the SQL fails.
try
{
if ((msg.getHeaders().containsKey("sqlQuery"))&&(!"".equals(msg.getHeaders().get("sqlQuery"))))
{
_log.debug("Executing: " + msg.getHeaders().get("sqlQuery"), UID);
jdbcTemplate.execute((String) msg.getHeaders().get("sqlQuery"));
_log.info("Query executed successfully.", UID);
}
result = "S";
} catch (Exception ex) {
ex.printStackTrace();
_log.error(ex, ex, UID);
}
JDBC Drivers is Microsoft JDBC Driver 4.2, connecting to a SQL Server 2014 database.
I've tried running this with a simple 'Select 1/0' which would obviously throw a divide by zero error, but we get a successful response.
2018-07-19 16:36:01,738|org.springframework.jdbc.datasource.DataSourceUtils|sqlFileChannelTaskExecutor-6|DEBUG|Returning JDBC Connection to DataSource
2018-07-19 16:36:01,738|org.springframework.integration.transformer.MessageTransformingHandler|sqlFileChannelTaskExecutor-6|DEBUG|org.springframework.integration.transformer.MessageTransformingHandler#c6d1b7 received message: GenericMessage [payload={UPDATED=1}, headers={UID=MCTest, errorChannel=logSqlErrorChannel, id=318f54b8-2889-22af-1009-e191550c75eb, sqlQuery=Select 1/0, timestamp=1532014561738}]
2018-07-19 16:36:01,738|org.springframework.beans.factory.support.DefaultListableBeanFactory|sqlFileChannelTaskExecutor-6|DEBUG|Returning cached instance of singleton bean 'integrationEvaluationContext'
2018-07-19 16:36:01,738|org.springframework.beans.factory.support.DefaultListableBeanFactory|sqlFileChannelTaskExecutor-6|DEBUG|Returning cached instance of singleton bean 'integrationConversionService'
2018-07-19 16:36:01,738|MCTest|sqlFileChannelTaskExecutor-6|DEBUG|SQL Step Started
2018-07-19 16:37:16,926|MCTest|sqlFileChannelTaskExecutor-6|DEBUG|Executing: Select 1/0
2018-07-19 16:37:22,530|org.springframework.jdbc.core.JdbcTemplate|sqlFileChannelTaskExecutor-6|DEBUG|Executing SQL statement [Select 1/0]
2018-07-19 16:37:28,278|org.springframework.jdbc.datasource.DataSourceUtils|sqlFileChannelTaskExecutor-6|DEBUG|Fetching JDBC Connection from DataSource
2018-07-19 16:37:28,278|org.springframework.jdbc.datasource.DriverManagerDataSource|sqlFileChannelTaskExecutor-6|DEBUG|Creating new JDBC DriverManager Connection to [jdbc:sqlserver://<Server>;databaseName=<Database]
2018-07-19 16:37:33,069|org.springframework.jdbc.datasource.DataSourceUtils|sqlFileChannelTaskExecutor-6|DEBUG|Returning JDBC Connection to DataSource
2018-07-19 16:37:33,069|MCTest|sqlFileChannelTaskExecutor-6|INFO |Query executed successfully.
Can anyone help explain why exceptions aren't getting captured/thrown?
share you query.. and use catch (ArithmeticException ae) where as if you have issues in understanding the 1/0 ArithmeticException.
hope it will work.
I'm having issues making a connection to an AS400 database inside of Play!.
My application.conf looks like:
db.default.driver="com.ibm.as400.access.AS400JDBCDriver"
db.default.url="jdbc:as400://SERVER;libraries=A,B,C;toolbox trace=all;trace=true"
db.default.username="user"
db.default.password="password"
I've set up jt400 in the classpath, and I can see under "external libraries" that it shows up and is available. But essentially I get an error message about failing to connect (on user/password I know works) and failure to execute isValid(), which is a function that can not be found inside of AS400JDBCConnection class.
[error] c.z.h.p.PoolBase - HikariPool-1 - Failed to execute isValid() for connection, configure connection test query. (com.ibm.as400.access.AS400JDBCConnection.isValid(I)Z)
[error] application -
! #72265nf0a - Internal server error, for (GET) [/] ->
play.api.Configuration$$anon$1: Configuration error[Cannot connect to database [default]]
at play.api.Configuration$.configError(Configuration.scala:154)
at play.api.Configuration.reportError(Configuration.scala:806)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:48)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:42)
at scala.collection.immutable.List.foreach(List.scala:381)
at play.api.db.DefaultDBApi.connect(DefaultDBApi.scala:42)
at play.api.db.DBApiProvider.get$lzycompute(DBModule.scala:72)
at play.api.db.DBApiProvider.get(DBModule.scala:62)
at play.api.db.DBApiProvider.get(DBModule.scala:58)
at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81)
Caused by: play.api.Configuration$$anon$1: Configuration error[Failed to initialize pool: com.ibm.as400.access.AS400JDBCConnection.isValid(I)Z]
at play.api.Configuration$.configError(Configuration.scala:154)
at play.api.PlayConfig.reportError(Configuration.scala:996)
at play.api.db.HikariCPConnectionPool.create(HikariCPModule.scala:70)
at play.api.db.PooledDatabase.createDataSource(Databases.scala:199)
at play.api.db.DefaultDatabase.dataSource$lzycompute(Databases.scala:123)
at play.api.db.DefaultDatabase.dataSource(Databases.scala:121)
at play.api.db.DefaultDatabase.getConnection(Databases.scala:142)
at play.api.db.DefaultDatabase.getConnection(Databases.scala:138)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:44)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:42)
Caused by: com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: com.ibm.as400.access.AS400JDBCConnection.isValid(I)Z
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:512)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:105)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:71)
at play.api.db.HikariCPConnectionPool$$anonfun$1.apply(HikariCPModule.scala:58)
at play.api.db.HikariCPConnectionPool$$anonfun$1.apply(HikariCPModule.scala:54)
at scala.util.Try$.apply(Try.scala:192)
at play.api.db.HikariCPConnectionPool.create(HikariCPModule.scala:54)
at play.api.db.PooledDatabase.createDataSource(Databases.scala:199)
at play.api.db.DefaultDatabase.dataSource$lzycompute(Databases.scala:123)
at play.api.db.DefaultDatabase.dataSource(Databases.scala:121)
Caused by: java.lang.AbstractMethodError: com.ibm.as400.access.AS400JDBCConnection.isValid(I)Z
at com.zaxxer.hikari.pool.PoolBase.checkDriverSupport(PoolBase.java:400)
at com.zaxxer.hikari.pool.PoolBase.setupConnection(PoolBase.java:375)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:346)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:506)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:105)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:71)
at play.api.db.HikariCPConnectionPool$$anonfun$1.apply(HikariCPModule.scala:58)
at play.api.db.HikariCPConnectionPool$$anonfun$1.apply(HikariCPModule.scala:54)
at scala.util.Try$.apply(Try.scala:192)
at play.api.db.HikariCPConnectionPool.create(HikariCPModule.scala:54)
I'm able to connect in other java-based projects using something like:
try {
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
Connection con = DriverManager.getConnection("jdbc:as400://" +
ApplicationAuthentication.server + "/" +
ApplicationAuthentication.library,
ApplicationAuthentication.user,
ApplicationAuthentication.password
);
} catch (Exception e) {
System.err.println(e);
throw new WebApplicationException(genericError, Response.Status.UNAUTHORIZED);
}
Guessing from the stacktrace, it appears that the connection returned from your driver is not playing well with the connection Hikari Connection Pool. Hikari is default connection pool in playframework.
Specifically, your exception trace shows that the Hikari CP is attempting to call isValid method on the connection object returned by your JDBC driver and then failing with java.lang.AbstractMethodError.
You can try switching to BoneCP connection pool and see if it helps. You can also check comments on this issue on hikari github issue list
Try adding the following to application.config
db.default.hikaricp.connectionTestQuery="SELECT 1"
Not tested in Play Framework but I had similar issue on spring framework and solved in that way.
Use liquibase datasource like below with connection-test-query
#Bean
#LiquibaseDataSource
public DataSource liquibaseDataSource() {
HikariDataSource dataSource = (HikariDataSource) DataSourceBuilder.create().url("url")
.username("username")
.password("password")
.type(HikariDataSource.class).build();
dataSource.setConnectionTestQuery("select 1 from sysibm.sysdummy1");
return dataSource;
}
I use the following properties file content:
driverClassName=org.apache.derby.jdbc.EmbeddedDriver
jdbcUrl=jdbc:derby:D:\\development\\databases\\test;create=true
connectionTimeout=3000
and
HikariConfig config = new HikariConfig(propertiesFilePath);
HikariDataSource ds = new HikariDataSource(config);
During
new HikariDataSource(config);
the following exception is thrown:
Caused by:
java.sql.SQLTransientConnectionException: HikariPool-0 - Connection is not available, request timed out after 3002ms.
kari.pool.HikariPool.getConnection(HikariPool.java:195)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:147)
at com.zaxxer.hikari.pool.HikariPool.initializeConnections(HikariPool.java:510)
What I can see is that the database directories are created.
What I am doing wrong?
derby version: 10.10.1.1
HikariCP version: 2.4.3
Update
Well the solution is pretty simple. The connection timeout was just to short.
If the database does not exist, the creation of the db just needs some time.
After increasing the connection timeout everything works fine.