Set Oracle 10g database connection timeout in Java - java

I tried to set a connection timeout with the following code:
public class ConnectionTimeout {
public static void main(String[] args) throws Exception {
String entry = "jdbc:oracle:thin:#xxx:1521:xxx";
Connection con=null;
Class.forName("oracle.jdbc.driver.OracleDriver");
DriverManager.setLoginTimeout(1);
con=DriverManager.getConnection(entry,"username","password");
Statement s=con.createStatement();
s.execute("select 1 from dual");
s.close();
con.close();
}
}
The instance xxx is not existing. But I get the following exception:
Exception in thread "main" java.sql.SQLException: E/A-Exception: Socket is not connected
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:255)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:387)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:439)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at my.package.connection.timeout.ConnectionTimeout.main(ConnectionTimeout.java:22)
How I can implement a timeout to an not existing or available Oracle database instance?
Edit:
If I set the DriverManager.setLoginTimeout(30); to 30 second, the exception happens so fast as before!

Your DriverManager.setLoginTimeout(1); sets the maximum time in seconds for the driver to wait while connecting to the database. In your case, it's set to 1.
To have no limit, set setLoginTimeout(0) where 0 means no limit.
I hope this helps.
Update if your instance xxx doesn't exists, how would you expect your Oracle Driver to connect to the database? It won't make any difference how long you set your loginTimeout there's not "host" to connect to.

Because, in Java doc, it shows: timeout in seconds, but in the implementation of JDBC Oracle, it is milliseconds.
You can try using a measure of milliseconds.

Related

Redshift server closes connection after 10 minutes

I have a statement that takes about 20 minutes to run, which is of the form:
create table new_table diststyle key distkey(column1) sortkey(column2)
as (select ....);
When I run it using an SQL IDE or with the psql command line client, the statement executes successfully but when I run it from my Java program, the server closes the connection after 10 minutes with the following exception:
org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [create table new_table diststyle key distkey(column1) sortkey(column2) as (select ....);];
SQL state [HY000]; error code [600001]; [Amazon](600001) The server closed the connection.;
nested exception is java.sql.SQLException: [Amazon](600001) The server closed the connection.
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:419) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:538) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at com.abc.mypackage.MyClass.myMethod(Myclass.java:123) [classes/:?]
Caused by: java.sql.SQLException: [Amazon](600001) The server closed the connection.
at com.amazon.support.channels.TLSSocketChannel.read(Unknown Source) ~[?:?]
Caused by: com.amazon.support.exceptions.GeneralException: [Amazon](600001) The server closed the connection.
at com.amazon.support.channels.TLSSocketChannel.read(Unknown Source) ~[?:?]
I'm using org.apache.commons.dbcp2.BasicDataSource to create connections. I've tried extending the timeout via defaultQueryTimeout, maxConnLifetimeMillis and socketTimeout but to no avail. The server keeps closing the connection after the same 10 minutes.
dataSource = new BasicDataSource();
dataSource.setUsername(dbUser);
dataSource.setPassword(dbPassword);
dataSource.setUrl(dbUrl);
dataSource.setDefaultAutoCommit(true);
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(true);
dataSource.setDriverClassName("com.amazon.redshift.jdbc41.Driver");
dataSource.setDefaultQueryTimeout(7200);
dataSource.setMaxConnLifetimeMillis(7200000);
dataSource.addConnectionProperty("socketTimeout", "7200");
How do I keep the connection alive for longer?
P.S. I do not have any problems establishing connections and running queries that take less than 10 minutes to finish.
You might want to extend your socket timeout.
Current it is 7200ms only:
dataSource.addConnectionProperty("socketTimeout", "7200");
check if the redshift server have a workload management policy that is timing out queries after 10 minutes.
your java code might be setting this policy
You need to set the tcpKeepAlive time to 1 min or less while getting the connection to redshift cluster.
Properties props = new Properties();
props.setProperty("user", user);
props.setProperty("password", password);
props.setProperty("tcpKeepAlive", "true");
props.setProperty("TCPKeepAliveMinutes", "1");
DriverManager.getConnection("jdbc:redshift://"+endpoint+":"
+port+"/"+database, props);
OP here- I was able to make it work by writing wrappers over BasicDataSource and Connection to poll active connection with isValid(int) every few minutes (any frequency more than once-per-10-minutes works). In hindsight, it seems that most timeout-related properties on BasicDataSource apply to connections which are in the pool but are not being used. setDefaultQueryTimeout and tcpKeepAlive + TCPKeepAliveMinutes did not work.
P.S. It has been a while since I resolved this problem and I do not have the code for the wrappers now. Here's a brief description of the wrappers.
WrappedConnection class takes a Connection object (conn) and a TimerTask object (timerTask) in its constructor and implements the Connection interface by simply calling the methods from conn. timerTask calls this.isValid(100) every few minutes as long as the connection is active. WrappedConnection.close stops timerTask and then calls conn.close.
WrappedBasicDataSource implements the DataSource interface, redirecting methods to a BasicDataSource object. BasicDataSourceWrapper.getConnection gets a connection from the aforementioned BasicDataSource and generates a WrappedConnection using the connection and a new TimerTask object.
I might have missed explaining some details but this is the gist of it.

MySQL connection reset in java

I have a java code that generate and fill tables to MySQL database.
The method is to create a connection to generate a table and then close that connection afterward.
Then create new connection to fill the table and so on.
I have about 14000 table to generate. The problem is that after generating about 800 tables I got this message and I have to restart mysql again.
Is there a cap to the number of connection I could create? is there anyway to increase it? Any Ideas?
Thanks
java.sql.SQLException: Communication link failure: java.net.SocketException, underlying cause: Connection reset
** BEGIN NESTED EXCEPTION **
java.net.SocketException
MESSAGE: Connection reset
STACKTRACE:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:189)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:1449)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1826)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1803)
at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:2353)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:750)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:1627)
at com.mysql.jdbc.Connection.<init>(Connection.java:427)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:395)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at db.DbConnection.establishConnection(DbConnection.java:21)
at db.DbActivities.addToDocSent(DbActivities.java:125)
at db.DbGeneration.main(DbGeneration.java:58)
** END NESTED EXCEPTION **

Oracle JDBC DriverManager.getConnection() hangs

We have several servers that each run an Oracle database 11g Release 11.2.0.1.0 - 64bit. We are connecting via JDBC like this:
public Connection createConnection(String drvClass, String connURL, String user, String pass)
throws ClassNotFoundException, SQLException {
Class.forName(drvClass);
Connection conn = DriverManager.getConnection(connURL, user, pass);
for (SQLWarning warn = conn.getWarnings(); warn != null; warn = warn.getNextWarning()) {
System.out.println("SQL Warning:");
System.out.println("State : " + warn.getSQLState());
System.out.println("Message: " + warn.getMessage());
System.out.println("Error : " + warn.getErrorCode());
}
return conn;
}
drvClass would be oracle.jdbc.OracleDriver. The program which tries to connect runs on each server. The database is reachable from out of other programs with the exact same connection properties.
It is also possible to let this program run on another server and let it connect to the problematic database. It can establish the connection.
The program does not work if it's running on the server locally. We tried both IP and servername.
On one server the code hangs at DriverManager.getConnection() an I cannot find out why. Does anyone have any idea what could cause this?
There is no entry about this in the DB logs.
Stacktrace of blocking thread:
"pool-27-thread-1" - Thread t#1483
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at oracle.net.ns.Packet.receive(Packet.java:239)
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:255)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:973)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:291)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:490)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:202)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:474)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at com.companyname.DBConnectionInternal.DBConnection.createConnection(DBConnection.java:19)
at com.companyname.exportadapter.ExportCollector.initDatabase(ExportCollector.java:259)
at com.companyname.exportadapter.ExportCollector.run(ExportCollector.java:120)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Locked ownable synchronizers:
- locked <50be77> (a java.util.concurrent.ThreadPoolExecutor$Worker)
If i set DriverManager.setLoginTimeout(10)
then i get
Io exception: Socket read timed out.
you may making some unneccessary connections.
make Connection class static
,whenever you are creating new connection check older is alive or close then and then you must create new connection other wise return old connection.
like
if(conn!=null & !conn.isClosed()){
// code for create connection
}
It also depends on how the database side is configured, so check it with DBA of your system.
I would like to suggest using Connection pooling.
hope this helps.
You might want to enable JDBC debug logging for the ojdbc driver: http://docs.oracle.com/cd/B28359_01/java.111/b31224/diagnose.htm
That might give you some information about what the driver is doing.
Have you tried telnet-ing to the database server from the client machine (to assert it's reachable)?
The server was misconfigured. For some reason it had a virtual adapter configured which returned an ip to which nothing could connect. From outside the resolving worked correctly. Don't know why it never timed out with the wrong IP though.

Unable to connect to Oracle 11g using jdbc

I'm trying to connect to Oracle 11g using jdbc as below but its giving me error. I had downloaded and kept jars in eclipse (ojdbc6dms.jar and ojdbc6dms_g.jar), but still its giving error
public static Connection getDatabaseConnection() throws SQLException,
InstantiationException, IllegalAccessException,
ClassNotFoundException {
Connection con = null;
// initialising drive
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
// load driver
con = DriverManager.getConnection(
"jdbc:oracle:thin:#10.16.52.79:1521:TST", "rep",
"Appe");
String dbName = con.getMetaData().getDatabaseProductName();
System.out.println(" Conected to DB " + dbName);
return con;
} // insertRecordsToDB
Exception in thread "main" java.lang.NoClassDefFoundError: oracle/dms/console/DMSConsole
at oracle.jdbc.driver.DMSFactory.<clinit>(DMSFactory.java:45)
at oracle.jdbc.driver.PhysicalConnection.createDMSSensors(PhysicalConnection.java:4203)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:629)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:218)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:29)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:538)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at
Just wondering in which jar has class oracle/dms/console/DMSConsole . Because when i checked those jars, this class is not available
The JDBC driver download page for Oracle 11g has the file ojdbc6dms.jar which contains oracle.jdbc.driver.DMSFactory.
EDIT: As per #JavaGeek's comment below, this jar does not actually contain the DMSConsole class. The required class is available in the Oracle Server installation, in the location $ORACLE_HOME/oc4j/lib/dms.jar. Server downloads are also available at Oracle TechNetwork

How to determine connection pool size programmatically?

Is there any way to determine database connection pool size (connection in used/connection remaining in connection pool) programmatically? We am using Hibernate with C3P0.
We are facing issues while connecting to db. Following exception is thrown and the data is not saved in db.
1005,MA,19/09/11 09:39:14,com.novosys.gtw.business.frontend.SnapshotMessageBusiness.save, Major: Cannot open connection
org.hibernate.exception.GenericJDBCException: Cannot open connection
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1354)
at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:342)
at $Proxy0.beginTransaction(Unknown Source)
at com.novosys.gtw.util.base.BaseBusiness.save(BaseBusiness.java:199)
at com.novosys.gtw.business.backend.receivesnapshotmessage.filter.SaveMessageFilter.decode(SaveMessageFilter.java:102)
at org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory$ProtocolDecoderImpl.doDecode(DemuxingProtocolCodecFactory.java:292)
at org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:133)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:158)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at com.novosys.gtw.business.backend.receivesnapshotmessage.filter.WhitelistFilter.messageReceived(WhitelistFilter.java:231)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at com.novosys.gtw.business.backend.receivesnapshotmessage.filter.MoniterFilter.messageReceived(MoniterFilter.java:92)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java:220)
at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:264)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.sql.SQLException: Connections could not be acquired from the underlying database!
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:529)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
at org.hibernate.connection.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:78)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
... 31 more
Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source.
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1319)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
... 34 more
We tried to resolve it by increasing connection pool size and also increasing no. of connections available at MySQL level, but of no use. We are now trying to sort of debug it to see if its due to connection pool size or due to MySQL connection size. We want to log no. of connection available/in use in connection pool size but could not get any help from google.
Environment: Java, Hibernate, C3P0, MySQL
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSessionFactory(datasource).getCurrentSession();
transaction = session.beginTransaction();
// db save called here
session.getTransaction().commit();
} catch (Exception e) {
Logger.write(LoggerConstant.MAJOR_ERROR, e.getMessage(), e, methodName);
} finally {
try {
if ((transaction != null) && (transaction.isActive())) {
transaction.rollback();
}
} catch (Exception e) {
Logger.write(LoggerConstant.CRITICAL_ERROR, e.getMessage(), e, methodName);
}
try {
if ((session != null) && (session.isOpen())) {
session.close();
}
} catch (Exception e) {
Logger.write(LoggerConstant.CRITICAL_ERROR, e.getMessage(), e, methodName);
}
}
I don't believe your problem is the connection pool, per se, but more generally a connection leak. This problem is commonly related to the use of HibernateDaoSupport.getSession() without properly pairing with HibernateDaoSupport.releaseSession(). In general, you want something like
public SomeObject getSomething()
{
Session session = null;
try
{
session = this.getSession();
Query query = session.createSQLQuery("SELECT * FROM SomeTable WHERE SomeClause").addEntity(SomeObject.class);
// extract object from query
return someObject;
}
finally
{
if (session != null)
this.releaseSession(session);
}
}
This can be automated by using a HibernateCallback. You do this by providing the query to this.getHibernateTemplate().executeFind which will use a session in Hibernate with automated resource management.
Apart from what ex0du5 has suggested, the exception trace also suggest following:
Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source.
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1319)
This implies that the connection pool was not able to acquire new connection FROM DATABASE.
Please check the MySQL log for any errors.
Check the maximum connection pool size and max number of connection setting on mysql configuration. (Its least likely that connection pool size will be more that max connection on mysql configuration, but plz make sure of this)
Also there is a way where in you can monitor all the parameters (including max connection setting) of C3P0 conenction pool.
To properly configure the connection pool size, you need to have metrics to investigate the connection usage patterns.
FlexyPool aims to aid you figuring our the right connection pool size, because it can monitor the following metrics:
concurrent connections histogram
concurrent connection requests histogram
data source connection acquiring time histogram
connection lease time histogram
maximum pool size histogram
total connection acquiring time histogram
overflow pool size histogram
retries attempts histogram
You might check the following articles:
FlexyPool, reactive connection pooling
Professional Connection Pool Sizing
The simple scalability equation

Categories

Resources