JTDS and JBOSS JDBC Connection Pool Problem, any solution? Maybe a custom ValidConnectionChecker? - jdbc

I'm facing a weird production problem. Environment is the following:
JBOSS 4.0.2
SQL Server 2005
Driver JTDS 1.2.5
From time to time the following szenario occurs.
A SQL command fails to Excute with
java.sql.SQLException: I/O Error: Read timed out
(I can live with that, if it just happens twice a day or so)
But from that moment on the connection seems to be wasted without the pool recognizing it, as I continously receive
java.sql.SQLException: Invalid state, the Connection object is closed.
from that moment on. The only thing that helps is restarting JBOSS. This occurs despite of the fact that I have
<check-valid-connection-sql>select getdate()</check-valid-connection-sql>
set up in my Datasource definition.
I was wondering if I can use a custom ValidConnectionChecker, that either rebuilds the connection itself, or explicitly throws a Exception to fix this. Maybe anyone has other suggestions.
Here is my complete DS definition.
<local-tx-datasource>
<jndi-name>MyDS</jndi-name>
<connection-url>jdbc:jtds:sqlserver://192.168.35.235:1433/MyDb;user=user1;password=pwd;appName=MyApp;loginTimeout=15;socketTimeout=120</connection-url>
<driver-class>net.sourceforge.jtds.jdbc.Driver</driver-class>
<user-name>user1</user-name>
<password>pwd</password>
<min-pool-size>10</min-pool-size>
<max-pool-size>25</max-pool-size>
<blocking-timeout-millis>60000</blocking-timeout-millis>
<idle-timeout-minutes>1</idle-timeout-minutes>
<check-valid-connection-sql>select getdate()</check-valid-connection-sql>
</local-tx-datasource>
Any help appriciated.
Regards

Try changing your driver class line to
net.sourceforge.jtds.jdbcx.JtdsDataSource.
net.sourceforge.jtds.jdbc.Driver doesn't implement the javax.sql.ConnectionPoolDataSource interface.
source:
http://jtds.sourceforge.net/faq.html#features

Probably too late the solution, but I am stuck with the jtds driver here. Hope this saves half an hour of your productive time.
The fix is to specify a validationQuery to the Apache dbcp2 Connection Pool implementation.
For jtds/sql server
I specified the spring configuration as follows:
<bean id="sqlServerDS" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" >
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="defaultReadOnly" value="true" />
<property name="validationQuery" value="select 1" />
</bean>
In case you are not using Spring, call setValidationQuery method on BasicDataSource in your java code.
BasicDataSource bds = new BasicDataSource();
bds.setValidationQuery("select 1");

Connection.isValid() isn't implemented in JTDS.
I found even catching the exception and forcing a complete restart of the connection didn't work.

Related

Oracle stale connection

Every once in a while in my app I get this error:
ERROR 2015-04-09 08:30:13,724 [http-bio-8080-exec-2] mojo.jdbc.MojoAlertDataAccess: Invalid or Stale Connection found in the Connection Cache
java.sql.SQLException: Invalid or Stale Connection found in the Connection Cache
at oracle.jdbc.pool.OracleImplicitConnectionCache.getConnection(OracleImplicitConnectionCache.java:421)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:395)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:179)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:157)
at mojo.jdbc.MojoAlertDataAccess.getAllAlertTypes(MojoAlertDataAccess.java:807)
So currently I have a datasource in Spring defined as:
<bean id="globalDSRead" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
<property name="connectionCachingEnabled" value="true" />
<property name="URL" value="${mojo.jdbc.read.url}"/>
<property name="user" value="${mojo.jdbc.read.username}"/>
<property name="password" value="${mojo.jdbc.read.password}"/>
<property name="connectionCacheProperties">
<value>
PropertyCheckInterval:10
MinLimit:1
MaxLimit:200
InitialLimit:1
ConnectionWaitTimeout:30
InactivityTimeout:30
ValidateConnection:true
</value>
</property>
</bean>
As far as I can tell this happens when the app has been sitting idle for a while, but it's not all together easy to reproduce.
Also - Another thing that occurs in this function is the retrieval of the connection can take a long time to come back, again this usually happens when the app's been sitting idle for a long time.
Anyone have any ideas whatcould be misconfigured?
Thanks
Yes, I have seen that before. I recommend to use Apache DBCP (https://commons.apache.org/proper/commons-dbcp/) for the connection pool management.

SQLException: No suitable driver in Jboss Fuse

I am using c3p0.ComboPooledDataSource to connect to my oracle database and here is the code snippet and i have deployed this application in Jboss Fuse ESB
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
<property name="jdbcUrl" value="jdbc:oracle:thin:#localhost:1523:xe" />
<property name="user" value="test" />
<property name="password" value="test" />
</bean
when i try to insert values into the database am getting
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask#339d05df -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception:
java.sql.SQLException: No suitable driver
at java.sql.DriverManager.getDriver(DriverManager.java:278)[:1.7.0_55]
when I use org.springframework.jdbc.datasource.SimpleDriverDataSource instead of ComboPooledDataSource it is working fine
I've previously had issues setting up connection pools in Fuse/OSGi because the connection pool bundle (in this case the bundle containing com.mchange.v2.c3p0.ComboPooledDataSource) doesn't include the driver it's using in its Import-Package. Could this be the problem?
If so, there are a number of options to resolve the problem. For example, you could, e.g.:
repackage the pool to include the Import-Package
make the JDBC driver a fragment bundle of the pool bundle
You'll find that searching for 'OSGI JDBC pool' normally fires up lots of additional articles and hints around this problem.

How do you use a scope Tomcat DataSource with Spring Batch?

I am currently using Spring Batch to import data from a SQL server. In order to make the datasource configurable I needed to "step scope" the datasource bean. However, this concerns me. If the datasource bean, which does connection pooling, is step scoped, then how can it manage connection in a pool and is there even a benefit to using it.
My datasource is configured as follows:
<bean id="dataSourceMssql" class="org.apache.tomcat.jdbc.pool.DataSource" scope="step">
<property name="driverClassName" value="${batch.mssql.driver}" />
<property name="username" value="${batch.mssql.user}" />
<property name="password" value="${batch.mssql.password}" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="3610" />
<property name="url"
value="${batch.mssql.connect}#{jobParameters['dburl']}:#{jobParameters['port']}/#{jobParameters['databaseName']}" />
</bean>
Why is it step scoped? Because I needed to retrieve the jobParameters to configure the datasource.
What do I want to know?
Will connection pooling still occur? (Perhaps the beans resources stay alive and are reclaimed)
I appreciate the help.
The scope "step" is only usable on spring batch beans. Other beans (Spring) only know the scope : singleton, prototype, request or session.
Normal way to handle this is to set these parameters in a properties file read by your applicatioonContext.xml.
JobParameters are used to pass Job related parameters (path, filename, date, seqNo etc) since a job with the same JobParameters won't be able to run twice.
EDIT: Is your job multithreaded? Because majority of the jobs created are single threaded! If your job is in fact single thread, i would ask myself why pooling connections is needed!
Regards

Spring disconnecting from Derby

I'm using Apache Derby with the Spring JdbcTemplate inside a web app running on Tomcat.
Spring is managing the data source. I've noticed that if I update the .war file and Tomcat undeploys/redeploys the app, I get this error:
java.sql.SQLException: Another instance of Derby may have already booted the database /tmp/manager_db/manager.
Restarting Tomcat fixes the problem, but as a purist, I'd like to clean things up properly when the webapp is undeployed.
The Embedded driver doesn't seem to have a 'close' method to put in the bean declaration under 'destroy-method'. I know the shutdown is normally achieved using a 'shutdown' connection URL, "jdbc:derby:;shutdown=true".
Any suggestions?
Here's the declaration in the Spring config file for my data source (the db won't be under /tmp/, just there for now).
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="url" value="jdbc:derby:/tmp/manager_db/manager;create=true"/>
<property name="username" value=""/>
<property name="password" value=""/>
</bean>
I think a better answer is to use the Tomcat JNDI data source pool with Spring. Spring's JDBC template will return the connection to pool when it's done.

Validating Connection Before Handing over to WebApp in ConnectionPooling

I have connection pooling implemented in spring using Oracle Data Source. Currently we are facing an issue where connections are becoming invalid after a period of time. (May be Oracle is dropping those idle connections after a while). Here are my questions:
Can Oracle database be configured to drop idle connections automatically after a specific period of time. Since we expect those connections to lie idle for a while; if there is any such configuration; it may be happening.
In our connection pooling properties in spring we didn't have "validateConnection" property. I understand that it validates the connection before handing it over to web application? But does that mean that if a connection passes validateConnection test then it'll always connect to database correctly. I ask this, as I read following problem here:
http://forum.springsource.org/showthread.php?t=69759
If suppose validateConnection doesn't do the whole 9 yards of ensuring that connection is valid, is there any other option like "testBeforBorrow" in DBCP , which runs a test query to ensure that connection is active before handing it over to webapp?
I'll be grateful if you could provide answers to one ore more queries listed above.
Cheers
You don't say what application server you are using, or how you are configuring the datasource, so I can't give you specific advice.
Connection validation often sounds like a good idea, but you have to be careful with it. For example, we once used it in our JBoss app servers to validate connections in the pool before handing them to the application. This Oracle-proprietary mechanism used the ping() method on the Oracle JDBC driver, which checks that the connection is still alive. It worked fine, but it turns out that ping() executes "select 'x' from dual' on the server, which is a surprisingly expensive query when it's run dozens of times per second.
So the moral is, if you have a high-traffic server, be very careful with connection validation, it can actually bring your database server to its knees.
As for DBCP, that has the ability to validate connections as their borrowed from the pool, as well as returned to the pool, and you can tell it what SQL to send to the database to perform this validation. However, if you're not using DBCP for your connection pooling, then that's not much use to you. C3PO does something similar.
If you're using an app server's data source mechanism, then you have to find out if you can configure that to validate connections, and that's specific to your server.
One last thing: Spring isn't actually involved here. Spring just uses the DataSource that you give it, it's up to the DataSource implementation to perform connection validation.
Configuration of data source "was" as follows:
<bean id="datasource2"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>org.apache.commons.dbcp.BasicDataSource</value>
</property>
<property name="url">
<value>ORACLE URL</value>
</property>
<property name="username">
<value>user id</value>
</property>
<property name="password">
<value>user password</value>
</property>
<property name="initialSize" value="5"/>
<property name="maxActive" value="20"/>
</bean>
have changed it to:
<bean id="connectionPool1" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
<property name="connectionCachingEnabled" value="true" />
<property name="URL">
<value>ORACLE URL</value>
</property>
<property name="user">
<value>user id</value>
</property>
<property name="password">
<value>user password</value>
</property>
<property name="connectionCacheProperties">
<value>
MinLimit:1
MaxLimit:5
InitialLimit:1
ConnectionWaitTimeout:120
InactivityTimeout:180
ValidateConnection:true
</value>
</property>
</bean>

Resources