We are running a websphere commerce site with an oracle DB and facing an issue where we are running out of db connections.
We are using a JDBCHelper singleton for getting the prepared statements and cosing the connections.
public static JDBCHelper getJDBCHelper() {
if (theObject == null){
theObject = new JDBCHelper();
}
return theObject;
}
public void closeResources(Connection con, PreparedStatement pstmt, ResultSet rs){
try{
if(rs!=null){ rs.close();}
}catch(SQLException e){
logger.info("Exception closing the resultset");
}try{
if(pstmt!=null) { pstmt.close(); }
}catch(SQLException e){
logger.info("Exception closing the preparedstatement");
}try{
if(con!=null){ con.close(); }
}catch(SQLException e){
logger.info("Exception closing the connection");
}
}
However when we try getting the connection using a prepStmt.getConnection() for passing to the close resources after execution it throws an sql exception. Any idea why? Does the connection get closed immediately after execution? And is there something wrong in our use of the singleton JDBCHelper?
EDIT
Part of the code which makes the prepared statement,executes and closes the connection
PreparedStatement pstmt = jdbcHelper.getPreparedStatement(query);
try{
//rest of the code
int brs = pstmt.executeUpdate();
}
finally{
try {
jdbcHelper.closeResources(pstmt.getConnection(),pstmt);
} catch (SQLException e1) {
logger.logp(Level.SEVERE,CLASS_NAME,methodName,"In the finally block - Could not close connection", e1);
}
}
Your connection will most likely come from a pool, and closing it actually will return the connection to the pool (under the covers). I think posting the code which gets the connection, uses it and closes it via JDBCHelper will be of more use.
Re. your singleton, I'm not sure why you're using this, since it doesn't appear to have anything to warrant it being a singleton. Check out Apache Commons DbUtils which does this sort of stuff and more besides.
This code seems to be written for single threaded operation only, as it's lacking any synchronisation code. The getJdbcHelper() method for instance is likely to create two JdbcHelpers. If I'm not mistaken there's even no guarantee that a second thread will see theObject, long after a primary thread has created it. Although they usually will, by virtue of the architecture the JVM runs on.
If you're running this inside a web server you're likely to be running into race issues, where two threads are modifying your connection at the same time. Unless you rolled your own connection pool or something.
Brian is right, use one of the freely available libraries that solve this (hard) problem for you.
Related
I'm using Spring JDBC and I've got this test method to connect to PostgreSQL DB (It's a example code, this isn't the original code):
public void toConnect() {
final String sql = "SELECT 1";
template.execute(sql);
}
If I catch the DataAccessException, and I call method getCause() the program trigger the PLSQException anyway (though finally printing the message that I set in the catch).
public void toConnect() throws CGConnException {
final String sql = "SELECT 1";
try {
template.execute(sql);
} catch (DataAccessException e) {
throw new CGConnException("CG : Error DataBase connection. - ", e.getCause());
}
}
The problem is than I can't handle the exception and I want than only print the Message of the catch, without the exception details.
If it's run with an error on config parameters or the PostgreSQL database is down, a PSQLException is generated and that is great but I need to control this exception. However JdbcTemplate.execute(sql) method throws a DataAccessException, therefore, doesn't possibly catch the PSQLException on try/catch block (or I don't know how to do). So, when run the program always appears the stack trace in the console:
2021-05-02 03:10:14.052 ERROR 73837 --- [ main] .PostgresClientTestConnectionApplication : Error : CG : Error DataBase connection.
In this case, I need to print only a log as "Connection Error" or something similar as the example above.
Thank you in advance.
Actually there is no mistake. The exception is handled and the program finally correctly when is catch it.
try {
template.execute(sql);
logger.error("Connection Successful . . .");
} catch (Exception e) {
logger.error("Error connection" + e.getMessage());
throw new CGConnException("CG : Error DataBase connection. - ", e);
}
In the run console it's print the associate stack trace because Spring internal classes to do it, but don't mean than we are doing something wrong or than no handle the exception.
Not sure about whether I should and how to close a Connection in SQLite.swift. Will it cause thread/memory leak?
Normally the database is closed when the Connection variable is out of its using scope and reclaimed by the trash-collecting system (in the deinit function). But sometimes it is one of your class's attributes, so you might want to close it manually in the middle of some functions. Hence this code works:
sqlite3_close(db.handle)
where db has the type of Connection. You can then override the database file or delete it, no warnings will be raised.
Anyways, I highly recommend you design your code in a cautious way to let the system frees the handle.
Although SQLite does close connections automatically. To avoid potential race conditions from dangling threads. I add this to the end of my generic Swift query function for completeness.
if sqlite3_close(db) != SQLITE_OK {
print("error closing database")
}
Where
var db: OpaquePointer?
var databaseFullPath: String = "" /// Location database.
if sqlite3_open(databaseFullPath, &db) != SQLITE_OK {
print("error opening database")
}
Additional Information:
sqlite3_close() documentation.
Sqlite connection will close automatically if u don't do it manually.
for e.g:
try {
conn.close();
}
catch (Exception ex) {
System.out.println ("Error");
return false;
}
I am writing a RESTful web service using spring 3 and I noticed that when I implemented my DAO's (I am using spring-jdbc for database access), the exceptions that get thrown are pretty generic, so i am not able to identify if the exception occurred because my database is down or my query failed.
sample code:
try {
Q q = jdbcTemplate.queryForObject(MY_QUERY, new Object[]{id}, new MyMapper());
return q;
} catch (DataAccessException e) {
// What is this exception ? database down ? query failed ?
}
Unless I know what exception is this during runtime, I can't send back reasonable error message to service client.
Any help is appreciated. Thanks
You shouldn't be trying to catch every single possible exception; code so that you don't run into the possibility of multiple user or programmer error type exceptions. Generally there are three type of exceptions that occur in every DAO regardless of what you do. (1) your database is down... imo if this is the issue you've got bigger problems. (2) user authentication error which is easy enough to catch and deal with (however you should probably be handling that situation on your RESTful front-end. (3) improper data. If you have bad data, just send the attempted data back and the reason for the exception.
try {
Q q = jdbcTemplate.queryForObject(MY_QUERY, new Object[]{id}, new MyMapper());
return q;
} catch (DataAccessException e) {
throw new DaoException("Could not retrieve q with ID: " + qID, e);
}
The method queryForObject only throws DataAccessException or IncorrectResultSizeDataAccessException. You shouldn't catch exception due to database connection failure at this level. However, in your DAO class, you normally have code to establish the dataSource which can be injected by Spring's IoC container. That part of code will throw exception if the database connection fails. You should catch DB failure exception there.
In my Java-Spring based web app I'm connecting to Cassandra DB using Hector and Spring.
The connection works just fine but I would like to be able to test the connection.
So if I intentionally provide a wrong host to CassandraHostConfigurator I get an error:
ERROR connection.HConnectionManager: Could not start connection pool for host <myhost:myport>
Which is ok of course. But how can I test this connection?
If I define the connection pragmatically (and not via spring context) it is clear, but via spring context it is not really clear how to test it.
can you think of an idea?
Since I could not come up nor find a satisfying answer I decided to define my connection pragmatically and to use a simple query:
private ColumnFamilyResult<String, String> readFromDb(Keyspace keyspace) {
ColumnFamilyTemplate<String, String> template = new ThriftColumnFamilyTemplate<String, String>(keyspace, tableName, StringSerializer.get(),
StringSerializer.get());
// It doesn't matter if the column actually exists or not since we only check the
// connection. In case of connection failure an exception is thrown,
// else something comes back.
return template.queryColumns("some_column");
}
And my test checks that the returned object in not null.
Another way that works fine:
public boolean isConnected() {
List<KeyspaceDefinition> keyspaces = null;
try {
keyspaces = cluster.describeKeyspaces();
} catch (HectorException e) {
return false;
}
return (!CollectionUtils.isEmpty(keyspaces));
}
Currently i am using spring declarative transaction manager in my application. During DB operations if any constraint violated i want to check the error code against the database. i mean i want to run one select query after the exception happened. So i am catching the DataIntegrityViolationException inside my Catch block and then i am trying to execute one more error code query. But that query is not get executed . I am assuming since i am using the transaction manager if any exception happened the next query is not getting executed. Is that right?. i want to execute that error code query before i am returning the results to the client. Any way to do this?
#Override
#Transactional
public LineOfBusinessResponse create(
CreateLineOfBusiness createLineOfBusiness)
throws GenericUpcException {
logger.info("Start of createLineOfBusinessEntity()");
LineOfBusinessEntity lineOfBusinessEntity =
setLineOfBusinessEntityProperties(createLineOfBusiness);
try {
lineOfBusinessDao.create(lineOfBusinessEntity);
return setUpcLineOfBusinessResponseProperties(lineOfBusinessEntity);
}
// Some db constraints is failed
catch (DataIntegrityViolationException dav) {
String errorMessage =
errorCodesBd.findErrorCodeByErrorMessage(dav.getMessage());
throw new GenericUpcException(errorMessage);
}
// General Exceptions handling
catch (Exception exc) {
logger.debug("<<<<Coming inside General >>>>");
System.out.print("<<<<Coming inside General >>>>");
throw new GenericUpcException(exc.getMessage());
}
}
public String findErrorCodeByErrorMessage(String errorMessage)throws GenericUpcException {
try{
int first=errorMessage.indexOf("[",errorMessage.indexOf("constraint"));
int last=errorMessage.indexOf("]",first);
String errorCode=errorMessage.substring(first+1, last);
//return errorCodesDao.find(errorCode);
return errorCode;
}
catch(Exception e)
{
throw new GenericUpcException(e.getMessage());
}
}
Please help me.
I don't think problem you're describing has anything to do with Transaction management. If DataIntegrityViolationException happens within your try() block you code within catch() should execute. Perhaps exception different from DataIntegrityViolationException happens or your findErrorCodeByErrorMessage() throwing another exception. In general, Transaction logic would be applied only once you return from your method call, until then you could do whatever you like using normal Java language constructs. I suggest you put breakpoint in your error error handler or some debug statements to see what's actually happening.