OracleDataSource connection caching - restarting connections? - oracle

Is it possible to set the Oracle connection cache to restart cached connections after a period of time?

You can use the new Universal Connection Pool. The class oracle.ucp.jdbc.PoolDataSource has apropriate methods.
e.g.
void setTimeToLiveConnectionTimeout(int timeToLiveConnectionTimeout)
throws java.sql.SQLException
see javadoc at: http://download.oracle.com/docs/cd/B28359_01/java.111/e11990/oracle/ucp/jdbc/PoolDataSource.html

Related

org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection

I sometimes notice below mentioned error in my springboot app logs.
org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
I suspect it could be because of exception thrown from #Transactional method ( only at times though).
Is it Ok to throw excaption from #Transactional method? or it is a bad practice?
Here is my service layer code
#Override
#Transactional
public void updateMessageStatus(String status, String sid, String errorCode) throws NotFoundException {
OutgoingMessage outgoingMessage = outgoingMessageRepository.findByResourceSid(sid);
if (outgoingMessage == null) {
throw new NotFoundException(ErrorCode.MESSAGE_NOT_FOUND, sid);
}
outgoingMessage.setStatus(status);
outgoingMessage.setUpdatedTime(Calendar.getInstance().getTime());
outgoingMessageRepository.save(outgoingMessage);
}
This usually happens when app is idle for longer time than the server’s connection timeout period.
So if a connection has been idle longer than this timeout value, it will be dropped by the server. By default, Hibernate uses its internal database connection pool library,
keeping the connection open to be reused later.
Hibernate reuses the idle connection which was already dropped by the server, hence we get JDBCConnectionExceptionis error.
What I noticed is even with the following database auto-reconnect setup should not work in this case.
spring.datasource.validation-query=select 1
spring.datasource.testOnBorrow=true
May be need to increase the pool size OR Entity Manager needs to be closed once the transaction is done.
spring.datasource.hikari.maximum-pool-size=10.
Please let me know if this worked for you.

How to find max connections available in Redis and how many are used and how many are free?

We are using Redis from the Spring boot app and we are getting below alert like flood
Exception occurred while querying cache : class org.springframework.data.redis.RedisConnectionFailureException Message: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the poolCause: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the poolMessage:Could not get a resource from the pool",
is it because of that their are no connections in the Redis Server ? or any other reason ?
How to find number of connections max available ? How to find how many are free ?
Could not get a resource from the pool
You have ran out of connections in Jedis pool on client side. Possible fixes:
Return connections to the pool properly (pool.returnResource()), if you are not doing it. Don't hold them when they are not needed. Don't disconnect regulairly. Be sure that commons-pool version is at least 1.6.
Increase pool size.
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(...);
Increase the time to wait when there are no connections available.
poolConfig.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
poolConfig.setMaxWait(...);
Update:
For server-side limitations see here: https://stackoverflow.com/a/51539038/78569

Liquibase in Spring boot application keeps 10 connections open

I'm working on a Spring Boot application with Liquibase integration to setup the database. We use a different user for the database changes which we configured using the application.properties file
liquibase.user=abc
liquibase.password=xyz
liquibase.url=jdbc:postgresql://something.eu-west-1.rds.amazonaws.com:5432/app?ApplicationName=${appName}-liquibase
liquibase.enabled=true
liquibase.contexts=dev,postgres
We have at this moment 3 different microservices in deployment and we noticed that for every running instance, Liquibase opens 10 connections and it never closes these connections unless we stop the application. This basically means that in development we regularly hit the connection limit of our Amazon RDS instance.
Right now, in development, 40 of 74 active connections are occupied by Liquibase. If we ever want to go to production with this, having autoscaling enabled for all the microservices, that would mean we'll have to over-scale the database in order not to hit any connection limits.
Is there a way to
tell liquibase to not use a connection pool of 10 connections
tell liquibase to stop or close the connections
So far I found no documentation on how to do this.
Thanks to the response of Slava I managed to fix the problem with following datasource configuration class
#Configuration
public class LiquibaseDataSourceConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(LiquibaseDataSourceConfiguration.class);
#Autowired
private LiquibaseDataSourceProperties liquibaseDataSourceProperties;
#LiquibaseDataSource
#Bean
public DataSource liquibaseDataSource() {
DataSource ds = DataSourceBuilder.create()
.username(liquibaseDataSourceProperties.getUser())
.password(liquibaseDataSourceProperties.getPassword())
.url(liquibaseDataSourceProperties.getUrl())
.driverClassName(liquibaseDataSourceProperties.getDriver())
.build();
if (ds instanceof org.apache.tomcat.jdbc.pool.DataSource) {
((org.apache.tomcat.jdbc.pool.DataSource) ds).setInitialSize(1);
((org.apache.tomcat.jdbc.pool.DataSource) ds).setMaxActive(2);
((org.apache.tomcat.jdbc.pool.DataSource) ds).setMaxAge(1000);
((org.apache.tomcat.jdbc.pool.DataSource) ds).setMinIdle(0);
((org.apache.tomcat.jdbc.pool.DataSource) ds).setMinEvictableIdleTimeMillis(60000);
} else {
// warnings or exceptions, whatever you prefer
}
LOG.info("Initialized a datasource for {}", liquibaseDataSourceProperties.getUrl());
return ds;
}
}
The documentation of the properties can be found on the site of Tomcat: https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html
initialSize: The initial number of connections that are created when the pool is started
maxActive: The maximum number of active connections that can be allocated from this pool at the same time
minIdle: The minimum number of established connections that should be kept in the pool at all times
maxAge: Time in milliseconds to keep this connection. When a connection is returned to the pool, the pool will check to see if the now - time-when-connected > maxAge has been reached, and if so, it closes the connection rather than returning it to the pool. The default value is 0, which implies that connections will be left open and no age check will be done upon returning the connection to the pool.
minEvictableIdleTimeMillis: The minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
So it does not appear to be a connection leak, it's just the default configuration of the datasource which is not optimal for Liquibase if you use a dedicated datasource. I don't expect this to be a problem if the liquibase datasource is your primary datasource.
Update: This has been fixed in 2.5.0-M2 and Liquibase now uses a SimpleDriverDataSource without a connection pool.
Original answer: This change to connection pool management was introduced in Spring Boot version 2.0.6.RELEASE, and only takes effect if you use Spring Boot Actuator. There is an actuator endpoint (enabled by default) which allows you to get change sets applied by Liquibase. For this to work Liquibase keeps its database connections open. You can disable the endpoint with management.endpoint.liquibase.enabled = false, in which case the connection pool used by Liquibase will be shutdown after the initial run.
GitHub issue related to this change: https://github.com/spring-projects/spring-boot/issues/13832
Spring Boot Actuator (see 12. Liquibase: https://docs.spring.io/spring-boot/docs/2.0.6.RELEASE/actuator-api/html/
I don't know why liquibase doesn't close a connection, maybe it's a bug and you should create an issue for that.
To set connection pool for liquibase you have to create a custom data source and mark it with #LiquibaseDataSource annotation.
Related issues provide more details:
Possibility to specify custom dataSource configuration for liquibase only
Add LiquibaseDataSource annotation

Glassfish 4.0 serializable coonection pools not working with Oracle XA transactions

I have a problem that I don't know how solve and researching the net has not helped me much. I declare in glassfish 4.0 asadmin console a serializable connection pool and its corresponding resource.
create-jdbc-connection-pool --datasourceclassname oracle.jdbc.xa.client.OracleXADataSource --maxpoolsize 8 --isolationlevel serializable --restype javax.sql.XADataSource --property Password=A_DB:User=A_DB:URL="jdbc\:oracle\:thin\:#localhost\:1521\:orcl" ATestPool
create-jdbc-resource --connectionpoolid ATestPool jdbc/ATest
Then inside a stateless bean I build a datasource via jndi as follows:
InitialContext ic = new InitialContext();
jndiDataSource = (DataSource) ic.lookup("jdbc/ATest");
and I'm getting connection as follows
jndiDataSource.getConnection();
Connections are properly obtained and released via finally clauses in each method we they are needed.
However, pairing serializable connection pool with XA data sources seems not to work, as getting first connections throws the following pair of exceptions in the order shown below
JTS5041: The resource manager is doing work outside a global transaction
oracle.jdbc.xa.OracleXAException
at oracle.jdbc.xa.OracleXAResource.checkError(OracleXAResource.java:1110)
RAR5029:Unexpected exception while registering component
javax.transaction.SystemException
at com.sun.jts.jta.TransactionImpl.enlistResource(TransactionImpl.java:224)
with the following
RAR7132: Unable to enlist the resource in transaction. Returned resource to pool. Pool name: [ ATestPool ]]]
RAR5117 : Failed to obtain/create connection from connection pool [ ATestPool ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: javax.transaction.SystemException]]
RAR5114 : Error allocating connection : [Error in allocating a connection. Cause: javax.transaction.SystemException]]].
Now if the connection pool is recreated without --isolationlevel serializable, then application works fine without any changes into the code. Also, if one keeps the isolation parameter and uses non-XA transactions as
--datasourceclassname oracle.jdbc.pool.OracleDataSource
--restype javax.sql.DataSource
then again application works without any changes into the code.
I was wondering if anyone could explain to me what could be wrong in the above setup and how to actually make serializable work with XA data sources. Thanks.
I think you need to enable useNativeXA.

Perform commit(), rollabck(), setAutoCommit(false) on JDBC Connection from CMT JTA

I have created glassfish connection pool with ResourceType as ConnectionPoolDataSource.So, glassfish will use the native connection pool implementation for connection pooling. I am not using XADatasource ResourceType as I don't want to perform any distributed transactions.
My application requires the use of TEMPERORY MYSQL table creation at run time. So I am using
the below code to get the connection from JNDI Datasource of glassfish.
#Resource(mappedName = "jdbc/xxxxx")
private DataSource dataSource;
public Connection getConnection() throws SQLException {
Connection con = dataSource.getConnection();
return con;
}
Now, My question is, Can I perform setAutoCommit(false), commit() and rollback(), close() on this Connection object????
In forum, I read that, we should not call these methods on Connection object, if we get the Connection from Container Managed Distributed Transaction (XADataSource) as its involved in distributed transactions.
But, I am getting this connection from non-distributed transactions.So, I can call those methods right???
Other question is, after performing db operations, If I call con.close(), will this connection go back to the connection pool again?

Resources