Try set initial pool size of database connections (spring-boot) - java

So, i have a application that uses spring-boot 1.4.0 and a Oracle database. I'm trying to define the number of connections of the pool in the application.properties, using these configs:
spring.datasource.driverClassName = oracle.jdbc.OracleDriver
spring.datasource.url = url
spring.datasource.username = username
spring.datasource.password = password
spring.datasource.maxActive= x
spring.datasource.initialSize= y
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1 from dual
And i'm using the query
select *from V$SESSION where username= 'username';
to check the database connections, but when i run the application it's always using 10 connections, despite what i define as the initialSize. I tried to check other stackoverflow answers and examples on GitHub and i don't know why it's not working, so i would appreciate if someone can help me. Thanks!

Spring Boot 1.4 does not bind the DataSource in the spring.datasource namespace anymore. Each supported connection pool implementations have a dedicated namespace for their respective keys. You are probably looking at older samples.
You first need to identify which connection pool you are using (if you're relying on the starter you should probably get the Tomcat JDBC pool, see spring.datasource.tomcat). Use your IDE to get the list of keys you can use.

Related

mysql db connection lost [duplicate]

I have an app that uses spring-boot,jpa-hiberanate with mysql.I am getting this error log
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 56,006,037 milliseconds ago. The last packet sent successfully to the server was 56,006,037 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
Here is my application.properties
# DataSource settings: set here configurations for the database connection
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = test
spring.datasource.password = test
spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate settings are prefixed with spring.jpa.hibernate.*
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy
To solve this issue I can use
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
But I checked that it's not recommended .So can anyone suggest me what should I do to overcome this error
The easiest way is to specify the autoReconnect property in the JDBC url, although this isn't the recommended approach.
spring.datasource.url = jdbc:mysql://localhost:3306/test?autoReconnect=true
This can give issues when you have an active connection and during a transaction something happens and a reconnect is going to happen. It will not give issues when the connection is validated at the start of the transaction and a new connection is acquired at the start.
However it is probably better to enable validation of your connections during the lifetime of your application. For this you can specify several properties.
First start by specifying maximum number of connections you allow for the pool. (For a read on determining the max poolsize read this).
spring.datasource.max-active=10
You also might want to specify the number of initial connections
spring.datasource.initial-size=5
Next you want to specify the min and max number of idle connections.
spring.datasource.max-idle=5
spring.datasource.min-idle=1
To validate connection you need to specify a validation-query and when to validate. As you want to validate periodically, instead of when a connection is retrieved from the pool (this to prevent broken connections in your pool).
spring.datasource.test-while-idle=true
spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1
NOTE: The usage of a validation-query is actually discouraged with as JDBC4 has a better/different way of doing connection validation. HikariCP will automatically call the JDBC validation method when available.
Now that you are also validating while a connection is idle you need to specify how often you want to run this query for the connections and when a connection is considered idle.
spring.datasource.time-between-eviction-runs-millis=5000 (this is the default)
spring.datasource.min-evictable-idle-time-millis=60000 (this is also default)
This all should trigger validation of your (idle) connections and when an exception occurs or the idle period has passed your connections will be removed from the pool.
Assuming you are using Tomcat JDBC as the connection pool this is a nice read of what and how to configure.
UPDATE: Spring Boot 2.x switched the default connection pool to HikariCP instead of Tomcat JDBC.

Connection to Db dies after >4<24 in spring-boot jpa hibernate

I have an app that uses spring-boot,jpa-hiberanate with mysql.I am getting this error log
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 56,006,037 milliseconds ago. The last packet sent successfully to the server was 56,006,037 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
Here is my application.properties
# DataSource settings: set here configurations for the database connection
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = test
spring.datasource.password = test
spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate settings are prefixed with spring.jpa.hibernate.*
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy
To solve this issue I can use
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
But I checked that it's not recommended .So can anyone suggest me what should I do to overcome this error
The easiest way is to specify the autoReconnect property in the JDBC url, although this isn't the recommended approach.
spring.datasource.url = jdbc:mysql://localhost:3306/test?autoReconnect=true
This can give issues when you have an active connection and during a transaction something happens and a reconnect is going to happen. It will not give issues when the connection is validated at the start of the transaction and a new connection is acquired at the start.
However it is probably better to enable validation of your connections during the lifetime of your application. For this you can specify several properties.
First start by specifying maximum number of connections you allow for the pool. (For a read on determining the max poolsize read this).
spring.datasource.max-active=10
You also might want to specify the number of initial connections
spring.datasource.initial-size=5
Next you want to specify the min and max number of idle connections.
spring.datasource.max-idle=5
spring.datasource.min-idle=1
To validate connection you need to specify a validation-query and when to validate. As you want to validate periodically, instead of when a connection is retrieved from the pool (this to prevent broken connections in your pool).
spring.datasource.test-while-idle=true
spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1
NOTE: The usage of a validation-query is actually discouraged with as JDBC4 has a better/different way of doing connection validation. HikariCP will automatically call the JDBC validation method when available.
Now that you are also validating while a connection is idle you need to specify how often you want to run this query for the connections and when a connection is considered idle.
spring.datasource.time-between-eviction-runs-millis=5000 (this is the default)
spring.datasource.min-evictable-idle-time-millis=60000 (this is also default)
This all should trigger validation of your (idle) connections and when an exception occurs or the idle period has passed your connections will be removed from the pool.
Assuming you are using Tomcat JDBC as the connection pool this is a nice read of what and how to configure.
UPDATE: Spring Boot 2.x switched the default connection pool to HikariCP instead of Tomcat JDBC.

Oracle FCF OSN Client Side Configuration

Good time!
First of all, here is my environment:
Java 1.7
Tomcat 7
Oracle UCP connection pool
Thin JDBC driver
Oracle 10g database with RAC and SCAN (some information)
I need to configure the Oracle FCF feature. There are several articles about it's configuration: Spring documentation (1), complete example (2), ...
I've performed all the steps described in the article (1) and I've also configured a UCP logging where I can see that FCF is actually enabled.
What is confusing for me is the following statement fro the second article:
FAST CONNECTION FAILOVER PREREQUISITES
...
5.) The JVM in which your JDBC instance is running must have
* oracle.ons.oraclehome set to point to your ORACLE_HOME. For example:
*
* -Doracle.ons.oraclehome=C:\oracle\product\10.2.0\db_1
...
Question:
My Oracle database (RAC) is located at a remote server and I use a thin JDBC driver, thus what should I do here (Do I really need to set uop this parameter, and, if yes, than how)? There is no point in the first article about configuring such a JVM parameter, it is only said that I need to set up the 'ONSConfiguration' parameter of a datasource where I should list all the RAC nodes...
UPDATE 1:
Also from the second article:
CLIENT-SIDE ONS CONFIGURATION
...
(2) ONS daemon on the client side
Example ons.config file for a client:
...
At the beginning of this article it is said that the 'client-side' is a java-based application, while the 'server-side' is a database (RAC). It is really required to creare the 'ons.config' file on a java-based-application-side in case of using a thin JDBC driver?
UDPADE 2:
From the Oracle documentation:
Remote Configuration
UCP for JDBC supports remote configuration of ONS through the SetONSConfiguration pool property. The ONS property value is a string that closely resembles the content of an ons.config file. The string contains a list of name=value pairs separated by a new line character (\n). The name can be: nodes, walletfile, or walletpassword. The parameter string should at least specify the ONS configuration nodes attribute as a list of host:port pairs separated by a comma. SSL would be used when the walletfile attribute is specified as an Oracle wallet file.
Applications that use remote configuration must set the oracle.ons.oraclehome system property to the location of ORACLE_HOME before starting the application. For example: java -Doracle.ons.oraclehome=$ORACLE_HOME ...
But how can I set the ORACLE_HOME variable when I have no local installation of Oracle database, that is what the thin driver is about, right?
If you want only use UCP pool , then you just need this setup :
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
pds.setONSConfiguration("nodes=10.247.43.111:4500, 10.247.43.112:4500");
pds.setFastConnectionFailoverEnabled(true);
where "nodes=10.247.43.111:4500, 10.247.43.112:4500" is list of ons listerers
10.247.43.111:4500 - remote ons listerner on node1
10.247.43.112:4500 - remote ons listerner on node2
etc.
see this good example:
http://www.idevelopment.info/data/Programming/java/jdbc/High_Availability/FastConnectionFailoverExampleThin.java
and this http://docs.oracle.com/cd/B19306_01/java.102/b14355/fstconfo.htm#CEGGDDFJ
ORACLE_HOME needed for local ONS demon connection.

SQL server connection issue using Spring

I found an issue connecting my web application using JDBC or Spring to a SQLServer database (not Express).
At some point of my code I call:
this.conn = DriverManager.getConnection(db_connect_string, db_userid, db_password);
and the application is running correctly but, it's waiting and doesn't proceed. The same happens with another web application with:
getJdbcTemplate().query(...)
If I take a look to the db using:
SELECT SPID, STATUS, PROGRAM_NAME, LOGINAME=RTRIM(LOGINAME), HOSTNAME, CMD
FROM MASTER.DBO.SYSPROCESSES
WHERE DB_NAME(DBID) = 'myDB' AND DBID != 0
I can see there is a connection opened but "AWAITING COMMAND". No exception is handled, it's just waiting for something.
The SQL Server Profiler for that connection (Audit login) returns:
-- network protocol: TCP/IP
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
It works until some weeks ago. I think it should be something related to SQLServer configuration, but I'm quite sure I didn't change anything. We can exclude a firewall issue because the connection is correctly created. Anyone could help me, please?
thanks,Andrea
As suggested by Mark Rotteveel it's a Java 1.6.0_29 bug.

Database connection encryption and integrity with ColdFusion and Oracle thin client

As ColdFusion datasource we are using the Oracle thin client to connect with the database. So, basically we are using a JDBC URL such as jdbc:oracle:thin:#... and as Driver Class oracle.jdbc.OracleDriver
This works successfully however we would like to set encryption and integrity parameters as well. In Java this is done similarly by setting a Properties object prior to getting a connection as follows:
Properties prop = new Properties();
prop.put("oracle.net.encryption_client", "REQUIRED");
prop.put("oracle.net.encryption_types_client", "( DES40 )");
prop.put("oracle.net.crypto_checksum_client", "REQUESTED");
prop.put("oracle.net.crypto_checksum_types_client", "( MD5 )");
...
OracleDataSource ods = new OracleDataSource();
ods.setProperties(prop);
ods.setURL("jdbc:oracle:thin:#localhost:1521:main");
Connection conn = ods.getConnection();
...
Is there a way that I can pass these parameters to the ColdFusion datasource. Ideally, I would love to do this centrally in such way that a change to all the cfquery or cfstoredproc is not needed.
I also know that in application servers such as Oracle AS there is an option when creating a datasource which says "Add Properties". In there you can add such properties. So, I was thinking of maybe creating a JNDI DS in the app. server and then magically connecting to it but this may have some impacts on the app.
Besides this I was also thinking of communicating with the CF datasource through the CF admin API (cfide.adminapi.administrator) and also the option of extending the Oracle driver so that when CF connects with it these params are already set.
I would love to have your professional opinion and suggestions on this.
I know this is an old question...
You absolutely can pass connection string properties to ANY ColdFusion datasource.
Once the datasource is open in CF ADMIN, open the Advanced Settings. The first option you can change in the Advanced Settings tab is "Connection String". This would be all the name-value pairs of parameters separated by ampersand (&) to be passed on the connection to the database.
For example:
encryption_client=REQUIRED&encryption_types_client=DES40&crypto_checksum_client=REQUESTED&crypto_checksum_types_client=MD5`
However, the answer to the OP, is that you can pass parameters along on the JDBC URL as well.
For example:
Using the Progress Datadirect driver, your JDBC URL might look like this:
jdbc:datadirect:oracle://server;SID=someSID;encryption_client=REQUIRED;encryption_types_client=DES40;crypto_checksum_client=REQUIRED;crypto_checksum_types_client=MD5
Just remember, that your params are separated by semicolons, not commas.
When defining a datasource, make sure you are using the right KIND of driver... Some features aren't available from the native datasource setup screens, so to use more advanced features, you may need to use OTHER.
All data sources in ColdFusion can be configured with a connection string. I would see if it is possible to pass your properties as part of the connection string.
To change the connection string open the data source in the CF admin and go to 'Advanced Settings'. There is a box there you can fill out.
If you figure that out then the whole process should be transparent those those using the data source.
I hope that helps some.

Categories