I deployed some apps in weblogic server. Few days ago, I traced logs and saw the error message:
2016-09-22 12:58:33,442 ERROR CommonService - ------- ERROR --------- java.sql.SQLException: Internal error: Cannot obtain XAConnection weblogic.common.resourcepool.ResourceDisabledException: Pool jdbc/*** is Suspended, cannot allocate resources to applications..
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResourceInternal(ResourcePoolImpl.java:377)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:342)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:329)
at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:417)
at weblogic.jdbc.common.internal.ConnectionPool.reserve(ConnectionPool.java:324)
at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:94)
at weblogic.jdbc.common.internal.ConnectionPoolManager.reserve(ConnectionPoolManager.java:63)
at weblogic.jdbc.jta.DataSource.getXAConnectionFromPool(DataSource.java:1677)
at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1475)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:446)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:403)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:364)
at [my-package].ConnectionHandler.newDatabaseConnection(ConnectionHandler.java:37)
I think that having a app leeks connections and doesn't return them to the pool
At temporary solution, I have to extended the the connection pool.
I try to research which apps made this problem and see that some strange codes below:
public class ConnectionHandler
{
..
public ConnectionHandler()
{
logger.trace("ConnectionHandler() constructor called");
}
static Connection newDatabaseConnection() throws SQLException
{
Connection conn;
try {
Context initContext = new InitialContext();
DataSource dataSource = (DataSource) initContext.lookup(LOOKUP_URL);
conn = dataSource.getConnection();
conn.setAutoCommit(false);
} catch (NamingException e) {
logger.error("------- ERROR ---------", e);
throw new ProcessingError("Could not obtain database connection!");
}
return conn;
}
}
This app (SOAP service) will using the code below to query data once having requests:
if (connectionHandler == null) {
connectionHandler = new ConnectionHandler();
}
try {
conn = connectionHandler.newDatabaseConnection();
// Some callable statements here
conn.commit();
logger.info("------- OK ---------");
} catch (SQLException e) {
logger.error("------- ERROR ---------", e);
} catch (InstantiationException e) {
logger.error("------- ERROR ---------", e);
} catch (IllegalAccessException e) {
logger.error("------- ERROR ---------", e);
} catch (DossierServiceException e) {
logger.error("------- ERROR ---------", e);
} finally {
jdbc.close(conn);
}
My confusions which I do not understand yet:
Using the static connection in multi threads is ok?
Create new class (ConnectionHandler) for each request and then get static connection?
Just close the connection without closing the ResultSet, Callable statements?
Could you help me explanation for these ones or having some solutions else to prevent this problem?
The method is static not the result it's returning. static method means that it's not necessary to have an instance of the enclosing class to call it
Yes, that's a mistake, but, not such a big deal
Yes, it would be better first to close the result set, statement and the connection, but this should do the job
The problem with this code is that there's no conn.rollback() in catch blocks and there may be uncaught runtime exceptions that will not be rolled back
Related
I have connection provider class as bleow to return connection.
public class ConnectionProvider {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection ConnectDB() throws ClassNotFoundException, SQLException {
try (Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/jspservlet_test","root", "root");
) {
return connection;
}
}
}
Here is main method to call connection provider.
public void Test() {
try {
Connection con = ConnectionProvider.ConnectDB();
PreparedStatement ps = con.prepareStatement("");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
But "com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed." error are always show at below line of code.
PreparedStatement ps = con.prepareStatement("");
Because, according to Oracle documentation, If use try with resources java 7 features, resources are auto close after try block even it's errors occurred or not. So even I returned the connection it's already closed.
Let me know, my usage logic is wrong?
How can I return this connection inside try with resource?
I tried many time googling for solution but does not get convenience answers for me.
Let me know your suggestion and feedback please.
What you can't do...
With a try-with-resources as you have it after you return the connection you return(d) is close(d). You can't return the connection from inside the try with resources.
What you can do...
Pass the connection (inside your try-with-resources) to a method that takes a connection. You can also use a ConnectionPool, and get the Connection when you need it (to create and execute a query).
Let me know, my usage logic is wrong?
The usage of 'try-with-resources' logic is wrong in this context, because the intention of ConnectDB() is to return a connection instance which could be actually used by the caller to send a SQL statement, but instead, the connection instance is getting auto-closed, before it could be used by the caller, because of using 'try-with-resources' construct of Java.
Quick how-to on try-with-resource and JDBC
Your ConnectionProvider's ConnectDB already declares it is throwing SQLException - so no need to catch it in here: (You should consider replacing this code with connection pool maybe)
public class ConnectionProvider {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection ConnectDB() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/jspservlet_test","root", "root");
}
}
Instead use try-with-resource in your test-class to clean up your code and focus on errors your SQL code
might have:
public void Test() {
try (Connection con = ConnectionProvider.ConnectDB();
PreparedStatement ps = con.prepareStatement("SELECT 1")) {
//Prepare your Statement
ps.setInt(1, 1);
//And another try-with-resource for the result - note the closing brace
try(ResultSet rs = ps.executeQuery()) {
while(rs.next()) {
//Handle your Result
System.out.println(rs.getString(1));
}
} // This closes try-with-resource. Exception will be rethron to be caught in outer catch!
} catch (SQLException e) {
//SQL is Broken - but only ONE catch to catch them all
e.printStackTrace();
}
}
That way you gain
Better readability for your code (no calls to close surrounded by finally and if != null)
Centralized error handling if anything in your SQL code breaks (so you can focus on functional error of "statement didn't run")
Better code quality: No need to worry about Cursors, Statements, Connections not being propery closed.
There are many similar questions but I am closing the connection in the finally block. I am testing so I am refreshing the same page often.
in the DAO ( which is called from the controller when the view is accessed)
try {
con= DB.getConnection();
st= connection.createStatement();
rs = statement.executeQuery(MY_QUERY);
while (rs.next()) {
...
}
} catch (SQLException e ) {
e.printStackTrace();
} finally {
try { rs.close(); } catch (Exception e) { /* ignored */ }
try { st.close(); } catch (Exception e) { /* ignored */ }
try { conn.close(); } catch (Exception e) { /* ignored */ }
}
in application.conf
db.default.driver=org.postgresql.Driver
db.default.url="jdbc:postgresql://hostname2/schema"
db.default.user="myuser"
db.default.password="mypass"
Inevitably after a few hours coding I hit the no more connections error. shouldn't the finally close the connection and return it to myuser's pool? Does hitting CTRL-D not close the connection?
Using: PostgreSQL, Java with Play2 framework, running with play run (testing/building stage)
UPDATE: still looking for a reason
Here's some working database code from a project I'm working on:
try
{
//Run a query.
statement = connection.createStatement();
statement.execute(db_request);
results = statement.getResultSet();
//Put the list of names into the table.
table = getTableResults(results);
if(table == null)
return null;
System.out.println("Running database command: " + db_request);
//End.
results.close();
statement.close();
connection.close();
}
catch (SQLException ex)
{
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
return null;
}
return table;
I run all the close statements at the end of the try block and only catch SQLException. If anything else is going on, the console prints the stack trace and shows me the exact line where it broke.
By the way, catch(Exception e) is a REALLY bad coding practice that causes Java to hide errors from you unless they're fatal. I imagine you'd get a lot more information from the stack trace that's automatically printed to the console if you removed those lines.
Seeing how Play Framework gives you play.Logger class, you could instrument that finally and the try {} catch {} inside it with
Logger.info("Something happened...");
and start getting the idea of whats happening for yourself. From top of my head - nothing looks wrong with your code. Do you know the max number of concurrent connections that your db supports btw? If its running in the cloud, there may be an artificial limitation as well.
I have a stateless session bean a method of which is used repetitively for running an SQL query within a plain JDBC connection. To avoid having to open and close connections too frequently, I came up with the following approach and wondering if it is a good practice:
I open the connection once in a method annotated #PostConstruct and close the connection in another method annotated #PreDestroy
The code works fine with no apparent memory leaks or any issues that I know of - just wondering if more experienced developers would agree if it is a good practice.
#PostConstruct
public void initBean() {
try {
conn = Connector.getConnection();
} catch (Exception e) {
// Handle errors for Class.forName
e.printStackTrace();
}
}
public String runTheQuery(String sql) {
String result ="";
try {
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
result = rs.getString(1);
rs.close();
pstmt.close();
} catch (SQLException se) {
// Handle errors for JDBC
}
return result;
}
#PreDestroy
public void endingTitles() {
System.out.println("Closing the JDBC connection...");
try {
rs.close();
conn.close();
pstmt.close();
} catch (SQLException se) {
// Handle errors for JDBC
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
// finally block used to close resources
try {
if (pstmt != null)
pstmt.close();
} catch (SQLException se2) {
}// nothing we can do
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
se.printStackTrace();
}// end finally try
}// end try
}
The best solution is to use DataSource
#Resource(mappedName="java:/DefaultDS")
DataSource dataSource;
public String runTheQuery(String sql) throws SQLException
Connection con = dataSource.getConnection();
try {
...
} finally {
con.close();
}
}
Data sources normally always have a minimum number of open connections, so in most cases there will be no real overhead getting a connection from a data source.
So it's only a valid practice, if you have measured before, and it it really solves an existing performance problem.
Otherwise it's not common, and therefore it's something like premature performance optimization.
Data sources offer additonal functionality: For example to check a connection, if it's still valid, before it gets injected. If you did it yourself, you would have to reimplement it. And there are possibly errors in that code.
Just came across a rather confusing exam question, and my lecturer is away on holidays, so I come to StackOverflow begging for help!
The question is as follows :
"Joe has his own JoeConnection class for making connections between his computer and other computers. The class provides the following constructor and instance methods :
JoeConnection( String address ): Make a connection with the URL address.
void writeLn( String text ) : Write text to the JoeConnection.
String readLn( ): Read a line of text from the JoeConnection.
void clode( ) : Close the JoeConnection.
Joe's connections regularly fail and this causes errors. Using proper exception handling, demonstrate how to use Joe's JoeConnection class to
make a JoeConnection with the URL http://students.chat.box
write "Hello world" to the JoeConnection
read in a string from the JoeConnection
close the connection.
The connection handling should provide as man details as possible about the cause of failure and print the stack trace which led to the failure.
I have no idea how to tackle this, but I assume it is something similar to this :
public class Test {
try {
JoeConnection connection = new JoeConnection(http://students.chat.box);
} catch {
connectionError e; printStacktrace();}
}
}
Can anyone please help me figure this out? Thanks a lot.
Without an indication of what exceptions are thrown and why, the only proper exception handling is no handling at all. Don't catch an exception if you don't know how to fix the problem that triggered it.
But the further instructions in your assignment introduce a different notion of "proper." You're supposed to print a stack trace. So catch the exception and print a stack trace. You were on the right track, but your syntax was wrong. Refer back to your textbook and lecture notes to remind yourself what the syntax is for catching exceptions (and for passing strings to functions, for that matter).
try {
JoeConnection connection = new JoeConnection("http://students.chat.box");
connection.writeLn("Hello world");
// etc
} catch (Exception e) {
e.printStackTrace();
}
"Proper exception handling" is a little vague. I agree with #Rob Kennedy's statement that no exception handling is appropriate unless you know why the exception is thrown and what should be done with it. Otherwise, the exception should be allowed to propagate. So, for example:
void foo(String address) throws JoeException {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
// Ensure the connection is closed when finished.
// This happens whether an exception occurs or not.
connection.close();
}
}
If you wanted to catch the exception just to print it, you could do something like this:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
connection.close();
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
There is a subtlety here that even experience Java programmers can miss, though. If an exception occurs while creating the connection, it doesn't need to be closed. If an exception occurs while writing to the connection, it does need to be closed; thus the finally clause. However, the act of closing can also throw an exception. If closing the connection throws an exception, only that exception will be thrown by the try statement. If the finally clause was reached as a result of the writeLn operation throwing an exception, the exception of the writeLn call will be effectively ignored. This is probably not what you want.
Instead, we can try something ugly like this:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
boolean normalCompletion = false;
try {
connection.writeLn("Hello World!");
normalCompletion = true;
} finally {
if (normalCompletion) {
// The writeLn operation completed normally.
// Propagate an exception thrown by the close operation.
connection.close();
} else {
// The writeLn operation completed abruptly.
// Ignore an exception thrown by the close operation.
try {
connection.close();
} catch (JoeException e) {
/* empty */
}
}
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
This looks (and is) syntactically hideous, but it does show "proper" exception handling of a sort. The language enhancement from Project Coin should clean this up a bit.
For starters, I can help you out with the syntax of what you wrote:
try {
JoeConnection connection = new JoeConnection("http://students.chat.box");
}
catch (JoeConnectionException e) {
e.printStacktrace();
}
I took the liberty of changing the linebreaks and renaming 'connectionError' as JoeConnectionException which looks more conventional to me.
You'll have to do something similar for the readLn, writeLn, and close method calls since it said that the connection regularly fails (i.e. not just while connecting).
Cheers, good luck.
Catching an exception should look like:
try {
JoeConnection conn = new JoeConnection(url);
} catch (YourExceptionClassNameHere e) {
e.printStackTrace();
}
Also: if you want to use a literal String, make sure you include the quotations. (It should be "http://students.chat.box".)
It's good to have a finally as well:
public class Test {
try {
JoeConnection connection = new JoeConnection(http://students.chat.box);
}
catch(Exception e) {
e.printStacktrace();
}
finally {
if(connection != null) {
connection.close();
}
}
}
Typically you handle exceptions if you know what to do with them (this involves error-recovery logic or wrapping an exception and throwing it to a higher level).
Assuming that each method throws an exception, you could do something like this for "maximum detail":
public class Test {
JoeConnection connection = null;
try {
connection = new JoeConnection("http://students.chat.box");
...
...
}
catch(OpenException e) {
System.out.println("Error while opening connection");
e.printStacktrace();
}
catch(WriteException e) {
System.out.println("Error while writing to connection");
e.printStacktrace();
}
catch(ReadException e) {
System.out.println("Error while reading from connection");
e.printStacktrace();
}
finally {
if(connection != null) {
connection.close();
}
}
}
I'm using this template:
try {
connection.setAutoCommit(false);
try {
// ... do something with that connection ...
connection.commit();
catch (SQLException exception) {
connection.rollback();
throw exception;
} finally {
connection.setAutoCommit(true);
}
} catch (SQLException exception) {
// log error
}
Is this the right way? How can this template be improved?
Your code should work fine. Do you get any errors or anything else?
Here's an example on using JDBC Transaction anyway
http://www.java2s.com/Code/Java/Database-SQL-JDBC/JDBCTransaction.htm
P.S. Specify your problem and I'll try to help.