Datasource too many open connection - java

I write in the contex.xml:
<Resource name="1_db" auth="Container" type="javax.sql.DataSource" maxActive="50" maxIdle="30" maxWait="10000" username="root" password="tunespray2008" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/1_db">
<Resource name="2_db" auth="Container" type="javax.sql.DataSource" maxActive="50" maxIdle="30" maxWait="10000" username="root" password="tunespray2008" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/2_db">
<Resource name="3_db" auth="Container" type="javax.sql.DataSource" maxActive="50" maxIdle="30" maxWait="10000" username="root" password="tunespray2008" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/3_db">
<Resource name="common" auth="Container" type="javax.sql.DataSource" maxActive="50" maxIdle="30" maxWait="10000" username="root" password="tunespray2008" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/common">
Java code:
public static Connection getDBConnection(String url)
{
Connection con = null;
try
{
Context ctx = new InitialContext();
BasicDataSource ds = (BasicDataSource)tx.lookup("java:comp/env/"+url);
con = ds.getConnection();
}catch(Exception e) {}
return con;
}
After that I call:
String url ="common";
LoginDAO ldcom = DAOFactory.getLoginDAO(url);
url ="1_db";
LoginDAO ldcom = DAOFactory.getLoginDAO(url);
StatusDAO ldcom = DAOFactory.getStatusDAO(url);
After that when we watch through JProfiler it shows a lot of open connections, though we call con.close(), rs.close() or st.close().
Please mention how can we use a Datasource in the proper way?

There are 2 pojnts:
1) Allways close connections (and other DB resources) in a finally block. In your case, it might be something:
Connection conn = null;
try {
conn = getDBConnection(xxx);
// do stuff with the connection
}
// optionally catch any errors that you can handle
finally {
// close other DB resources that depend on conn, e.g. Statements, ResultSets
if( conn != null ) try { conn.close(); }
catch(Exception ignore) {}
}
2) The open connections you are seeing are probably the connection pool. Creating DB connections with DriverManager.getConnection() is an expensive (time consuming) process. In an application server environment, where there are many concurrent requests, creating a new connection per request would be a performance killer. The javax.sql.Datasource wraps a connection pool managed by the application server. When you close() a connection taken from that pool (the Datasource) it is not destroyed, rather returned to the pool for future usage.

Related

Not able to connect to XA datasource using JNDI

I am trying to connect my java spring batch application to datasource using JNDI. My application requires XA datasource. I tried to configure normal datasource using below code and it seems to connect to it perfectly. But when i try to change the driver class to XA(oracle.jdbc.xa.client.OracleXADataSource) it doesn't seem to connect.i tried changing the type to javax.sql.XADataSource. Can someone tell me if i need to set additional properties for XA connectivity ?
<Resource name="jdbc/DS-ref"
auth="Container"
type="javax.sql.DataSource"
username="user"
password="password"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#xxx"
initialSize="20"
maxWaitMillis="15000"
maxTotal="75"
maxIdle="20"
testOnBorrow="true"
validationQuery="select 1 from dual" />
If i change the code in context.xml, I get error saying " Name [jdbc/DS-ref] is not bound in this Context. Unable to find [jdbc]."
Context.xml
<Resource name="jdbc/DS-ref"
auth="Container"
type="javax.sql.XADataSource"
username="user"
password="password"
driverClassName="oracle.jdbc.xa.client.OracleXADataSource"
url="jdbc:oracle:thin:#xxx"
initialSize="20"
maxWaitMillis="15000"
maxTotal="75"
maxIdle="20"
testOnBorrow="true"
validationQuery="select 1 from dual" />
web.xml
<resource-ref id="ResourceRef_CrcDataSource">
<description></description>
<res-ref-name>jdbc/DS-ref</res-ref-name>
<res-type>javax.sql.XADataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
datasource.java
// Use JNDI via Spring
Object tmpDs;
setResourceRef(true); // Make "java:comp/env/" prefix optional
try {
log.debug("pJndiName" +pJndiName);
tmpDs = lookup(pJndiName, DataSource.class);
log.debug("tmpDs"+tmpDs);
}
catch (Exception e) {
throw new RuntimeException("Error looking up DataSource via JNDI. jndiName: " + pJndiName, e);
}
if (null == tmpDs) {
throw new RuntimeException("DataSource JNDI lookup returned null. jndiName: " + pJndiName);
}
if (!DataSource.class.isInstance(tmpDs)) {
throw new RuntimeException("Illegal class returned by DataSource JNDI lookup. " + "jndiName: "
+ pJndiName + ", returned class: " + tmpDs.getClass().getName());
}
return (DataSource) tmpDs;

Hibernate passing a null connection to doReturningWork

Intermittently hibernate is passing me a null connection in this execute method
return session.doReturningWork(new ReturningWork<MyIterator<MyVO>>() {
#Override
MyIterator<MyVO> execute(Connection connection) throws SQLException {
PreparedStatement ps = null;
String preparedSql = "EXEC MyDB.dbo.MySP ?, ?";
ps = connection.prepareStatement(preparedSql); // <-- NPE !
The app is running in tomcat and connecting through a firewall with ports opened to SQL Server.
Any idea why that could be - here is my connection pool config
<Resource name="xxx"
auth="Container"
type="javax.sql.DataSource"
username="username"
password="password"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
maxActive="200"
maxIdle="0"
maxWait="1000"
initialSize="1"
minIdle="0"
minEvictableIdleTimeMillis="300000"
url="jdbc:sqlserver://IP\INST\databasename"
SelectMethod="cursor"
validationQuery="select 1"
testOnBorrow="true"
logAbandoned="true"
removeAbandoned="true"
removeAbandonedTimeout="600"/>

JNDI DataSource configuration in Tomcat 7

I am new to JNDI and I am trying to get my db connection working. So far no luck.
I either get a message stating: "Name [java:comp/env] is not bound in this Context. Unable to find [java:comp]"
or I received a time out.
Here's information about my current configuration.
Tomcat: Apache Tomcat/7.0.29
JMV: 1.7.0_06-b24
OS: Win 10 Pro
Tomcat\conf\web.xml
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/myDatabaseName</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Tomcat\conf\context.xml
<ResourceLink type="javax.sql.DataSource"
name="jdbc/localRemarket"
global="jdbc/remarket"
/>
I also tried to put the resource in context.xml to make sure it's findable:
<Resource
type="javax.sql.DataSource"
name="jdbc/myDatabaseName"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/myDatabaseName"
username="myUsername"
password="myPassword"
maxActive="1500"
maxIdle="200"
maxwait="-1"
testOnBorrow="true"
testOnReturn="true"
testWhileIdle="true"
validationQuery="SELECT 1"
timeBetweenEvictionRunsMillis="2000"
minEvictableIdleTimeMillis="15000"
removeAbandoned="true"
removeAbandonedTimeout="5"
/>
Tomcat\conf\server.xml
<Resource
type="javax.sql.DataSource"
name="jdbc/myDatabaseName"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/myDatabaseName"
username="myUsername"
password="myPassword"
maxActive="1500"
maxIdle="200"
maxwait="-1"
testOnBorrow="true"
testOnReturn="true"
testWhileIdle="true"
validationQuery="SELECT 1"
timeBetweenEvictionRunsMillis="2000"
minEvictableIdleTimeMillis="15000"
removeAbandoned="true"
removeAbandonedTimeout="5"
/>
java code:
Connection conn;
public void openMyConnection() {
try {
Properties props = new Properties();
props.put("java.naming.factory.initial", "org.apache.naming.java.javaURLContextFactory");
InitialContext ctx = new InitialContext(props);
Context envCtx = (Context) ctx.lookup("java:comp/env"); // <<<<< PRB HERE
// error message : Name [java:comp/env] is not bound in this Context. Unable to find [java:comp]
org.apache.tomcat.jdbc.pool.DataSource ds = (org.apache.tomcat.jdbc.pool.DataSource) envCtx.lookup("jdbc/localDB");
conn = ds.getConnection();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
if I change
props.put("java.naming.factory.initial", "org.apache.naming.java.javaURLContextFactory");
for
props.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
I get :
Receive timed out
I have reviewed many posts related to JNDI including the following two that were the most helpful:
http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html
and
https://examples.javacodegeeks.com/enterprise-java/tomcat/tomcat-datasource-jndi-example/
Please note that I read the How to configure jndi DataSource in Tomcat 7 but it doesn't provide a solution for my problem.
Can anyone please help resolve this issue?
It worked for me, when I configured the datasource directly in the webapp (file META-INF/context.xml):
<Context >
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="scott"
password="tiger"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#127.0.0.1:1521:mysid"
maxActive="8"
maxIdle="4"/>
</Context>

Tomcat jdbc connection pool, does not release connections after using

What may be reason for tomcat does not release connections after using?
Herem is my config
<Resource name="jdbc/DataSource" auth="Container"
type="javax.sql.DataSource" username="))" password="))"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="))"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
initialSize="55"
maxActive="55" maxIdle="55" maxWait="15000"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1 FROM DUAL"
validationInterval="20000"
timeBetweenEvictionRunsMillis="30000"
removeAbandoned="true"
removeAbandonedTimeout="60"
/>
You still need to call connection.close() in your code to have the connection released to the pool. It does not happen automatically.
You can configure the pool to detect "left over connections" wiht:
removeAbandoned="true"
removeAbandonedTimeout="60"
connection inactive for longer than given number of seconds will be closed automatically and recycled by the pool
The most probable is that you don't close connections after using them.
It can happens for example if you don't manage correctly exceptions.

NoInitialContextException

I have a problem.
I want to connect to database using JDBC, I have Tomcat server. For this I use connection pool.
According to Internet tutorials I've written:
context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/Server" docBase="dbcp" debug="5"
reloadable="true" crossContext="true">
<Resource name="jdbc/TestDB" auth="Container"
type="javax.sql.DataSource" removeAbandoned="true"
removeAbandonedTimeout="30" maxActive="100"
maxIdle="30" maxWait="10000" username="root"
password="newpass"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/delta_server"/>
</Context>
web.xml :
<resource-ref>
<description>DB Connection Pooling</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
and I try to connect...
Connection conn=null;
DataSource ds;
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:comp/env");
ds = (DataSource) envContext.lookup("jdbc/TestDB");
conn = ds.getConnection();
But I get a mistake:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
What to do???

Categories