Thread with infinite Loop stops after catching some Exception - java

I have written following code. i want when control becomes 1 the infinite loop should stop. Otherwise it keeps on updating the SQL database after regular period of time. Some kind of exception is causing it to the thread to terminate. I am not able to figure it out. Can anybody help with it.
public void run()
{
while(true)
{
System.out.println("I am working t asfbjakhbfjabf");
synchronized(lock)
{
if(control==1)
{
return;
}
}
try
{
Thread.sleep(wTIME);
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url+dbName,userName,password);
String st="SELECT count FROM ThreadResults WHERE ThreadNo = "
+t;
Statement stmt = conn.createStatement();
stmt.execute(st);
ResultSet resultSet = stmt.getResultSet();
boolean b=resultSet.next();
synchronized(WebCrawler.seed.lock6)
{
float t1=(System.currentTimeMillis()-time)/60000;
if(b)
{
String s2="UPDATE ThreadResults SET count = "+WebCrawler.seed.count+", time = "+t1+" WHERE ThreadNo = "+t;
System.out.println("updated count");
stmt.executeUpdate(s2);
}
else
{
String s1="INSERT ThreadResults VALUES("+t+" ,"+WebCrawler.seed.count+" ,"+t1+")";
System.out.println("inserting count");
stmt.executeUpdate(s1);
}
}
resultSet.close();
conn.close();
}
catch(InterruptedException | ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException c)
{
System.out.println("caught in thread resilt updation "+ c.getMessage());
}
}
}

Although this is not a preferred way to schedule a repeated task, you can fix it by catching Throwable instead of your explicit list of exceptions. That way you will make sure you catch anything that can theoretically be thrown. Be sure to print the whole exception stacktrace, not just the message.
When you fix the catching, you will need to additionally fix the cleanup logic: put the close statements into a finally. Better yet, rewrite your code to use Automatic Resource Management. The syntax is try (Statement stmt = conn.createStatement()) { ... }.
The proper way to schedule a repeated task is by using the Executors:
final ScheduledExecutorService sched = Executors.newSingleThreadScheduledExecutor();
sched.scheduleWithFixedDelay(task, 0, wTIME, TimeUnit.MILLISECONDS);

You can write
catch(Exception e)
instead of what you wrote. It will catch all exceptions.

Related

JDBC multiple connections has same performance as single connection

I wrote a simple java program to use JDBC to run 20 queries to fetch data from a view
int connectionSize = 10;
ds.init(connectionSize, settings);
ExecutorService executor = Executors.newFixedThreadPool(10);
try {
stopwatch.start();
for (int i = 0; i < 20; i++) {
executor.execute(new Runnable() {
#Override
public void run() {
String sql = String.format("select * from viewA where userId in (%s)", randomUserIds(5));
PreparedStatement ps = null;
Connection conn = null;
try {
while ((conn = ds.getConnection()) == null) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
logger.info("conn: " + conn.toString());
ps = conn.prepareStatement(sql);
ps.executeQuery();
ps.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (conn != null) {
ds.returnConnection(conn);
}
}
}
});
}
executor.shutdown();
boolean finished = executor.awaitTermination(10, TimeUnit.MINUTES);
stopwatch.stop();
logger.log(Level.INFO, "Query Complete in " + stopwatch);
} catch (Exception ex) {
ex.printStackTrace();
}
e.g. select * from ViewA where userId in (random few user Ids)
I used a single connection, and inside a for loop executed the 20 queries in a sequential way
I set up 10 connections in a pool and running the 20 queries in 10 threads
I expected the second approach would use less time to finish the 20 queries, but after testing, the results show me these two approaches return similar time consumption.
I can confirm when I was running the second approach, it created 10 sessions in db.
Is the second approach supposed to give a better performance than the first one? What would be the problem to make the second performance same as the first one?

Java ResultSet is not being closed properly

I have a Java application with many code snippets like the example below. Very simple querying of an Oracle database. Valid data is returned and parsed, then the close() functions are called.
ResultSet rs = null;
Statement stmt = null;
try
{
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM example");
while (rs.next())
{
// do stuff
}
rs.close();
stmt.close();
System.out.println("test1");
}
catch (Exception e)
{
System.out.println("error1");
}
I started encountering a "maximum cursors exceeded" error. I checked my methods to determine whether ResultSets are not being closed. The catch clause was never triggered, and "test1" was printed every single time. Which means the rs.close() and stmt.close() lines are NOT being skipped. Yet the ResultSets are not actually being closed.
I added a finally clause and it cleared up the issue.
finally
{
if (rs != null)
{
try
{
rs.close();
System.out.println("test2");
}
catch (Exception e)
{
System.out.println("error2");
}
}
if (stmt != null)
{
try
{
stmt.close();
System.out.println("test3");
}
catch (Exception e)
{
System.out.println("error3");
}
}
}
OUTPUT:
test1
test2
test3
My question is, why do rs.close() and stmt.close() need to be called twice? The calls in the try clause appear to do nothing. Yet I call them again in the finally clause, and they are successful. How is this possible?
Use try-with-resources (Java 7+):
try (Statement stmt = conn.createStatement()) {
try (ResultSet rs = stmt.executeQuery("SELECT * FROM example")) {
while (rs.next()) {
// do stuff
}
System.out.println("test1");
}
} catch (Exception e) {
System.out.println("error1");
}
No, no need to call twice
No, there is no need in JDBC to be calling close twice. I suspect something else is going on.
We cannot tell for sure what is going on in your code with certainty. We cannot know if your supposedly second call actually fixed the problem. The documentation for Statement::close, for example, says:
Calling the method close on a Statement object that is already closed has no effect.
try-with-resources
As the Answer by Andreas suggests, you should be using a try-with-resources.
See:
Java 7 tech note on try-with-resources.
Oracle Tutorial.
Java 9 enhancement to try-with-resources, using previously-created variable within Try-With-Resource Statement.
Use try-with-resources for JDBC and also for any resource implementing AutoCloseable.
You can put one or more resources in your try( … ). Separate with semi-colons, the last semi-colon being optional. Java will take of tracking the resources, each being closed in the reverse order of being opened. If an exception occurs in the middle, Java knows not to try closing the null resource objects. This significantly simplifies your coding.

Try / Try-with-resources and Connection, Statement and ResultSet closing

I have recently having some discussions with my professor about how to handle the basic jdbc connection scheme. Suppose we want to execute two queries, this is what he proposes
public void doQueries() throws MyException{
Connection con = null;
try {
con = DriverManager.getConnection(dataSource);
PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
PreparedStatement s2 = con.prepareStatement(selectSqlQuery);
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
ResultSet rs = s2.executeQuery();
rs.close();
s2.close();
s1.close();
} catch (SQLException e) {
throw new MyException(e);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException e2) {
// Can't really do anything
}
}
}
I don't like this approach, and I have two questions about it:
1.A) I think that, if any exception is thrown where we do 'other things', or in the line rs.close() or s2.close() then s1 wouldn't have been closed when the method ends. Am I right about that?
1.B) The professor keeps asking me to explicitly close the ResultSet (even when the Statement documentation makes clear that it will close the ResultSet) She says that Sun recommends it. Is there any reason to do so?
Now this is what I think is the correct code for the same thing:
public void doQueries() throws MyException{
Connection con = null;
PreparedStatement s1 = null;
PreparedStatement s2 = null;
try {
con = DriverManager.getConnection(dataSource);
s1 = con.prepareStatement(updateSqlQuery);
s2 = con.prepareStatement(selectSqlQuery);
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
ResultSet rs = s2.executeQuery();
} catch (SQLException e) {
throw new MyException(e);
} finally {
try {
if (s2 != null) {
s2.close();
}
} catch (SQLException e3) {
// Can't do nothing
}
try {
if (s1 != null) {
s1.close();
}
} catch (SQLException e3) {
// Can't do nothing
}
try {
if (con != null) {
con.close();
}
} catch (SQLException e2) {
// Can't do nothing
}
}
}
2.A) Is this code correct? (Is it guaranteed that all will be closed when the method ends?)
2.B) This is very large and verbose (and it gets worse if there are more Statements) Is there any shorter or more elegant way to do this without using try-with-resources?
Finally this is the code I like the most
public void doQueries() throws MyException{
try (Connection con = DriverManager.getConnection(dataSource);
PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
PreparedStatement s2 = con.prepareStatement(selectSqlQuery))
{
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
ResultSet rs = s2.executeQuery();
} catch (SQLException e) {
throw new MyException(e);
}
}
3) Is this code correct? I think my professor doesn't like this way because there is no explicit close of the ResultSet, but she has told me that she is fine with it as long as in the documentation it is clear that all is closed. Can you give any link to the official documentation with a similar example, or based in the documentation show that there is are no problems with this code?
tl;dr
In theory closing the statement closes the result set.
In practice, some faulty JDBC driver implementations failed to do so, notoriously. Thus the advice from your instructor that she learned from the School Of Hard Knocks.
Unless you are familiar with every implementation of every JDBC
driver that might be deployed for your app, use
try-with-resources to auto-close every level of your JDBC
work such as statements and result sets.
Use try-with-resources syntax
None of your code is fully using try-with-resources. In try-with-resources syntax, you declare and instantiate your Connection, PreparedStatement, and ResultSet in parentheses, before the braces. See Tutorial by Oracle.
While your ResultSet is not being explicitly closed in your last code example, it should be closed indirectly when its statement is closed. But as discussed below, it might not be closed because of faulty JDBC driver.
AutoCloseable
Any such objects implementing AutoCloseable will automatically have their close method invoked. So no need for those finally clauses.
How do you know which objects are auto-closable and which are not? Look at their class documentation to see if it declares AutoCloseable as a super-interface. Conversely, see the JavaDoc page for AutoCloseable for a list of all the bundled sub-interfaces and implementing classes (dozens actually).
For example, for SQL work, we see that Connection, Statement, PreparedStatement, ResultSet, and RowSet are all auto-closable but DataSource is not. This makes sense, as DataSource stores data about potential resources (database connections) but is not itself a resource. A DataSource is never “open” so no need to close.
See Oracle Tutorial, The try-with-resources Statement.
Code example
Your last code example is getting close to good, but should have wrapped ResultSet in a try-with-resources statement to get automatically closed.
To quote ResultSet JavaDoc:
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
As your teacher has been suggesting, there have been serious flaws in some JDBC drivers that failed to live up to the promise of the JDBC spec to close the ResultSet when its Statement or PreparedStatement is closed. So many programmers make a habit of closing each ResultSet object explicitly.
This extra duty is easier now with the try-with-resources syntax. In real work you’ll likely have a try-else around all your AutoCloseable objects such as ResultSet anyways. So my own opinion is: Why not make it a try-with-resources + else? Does not hurt, makes your code more self-documenting about your intentions, and it might help if your code ever encounters one of those faulty JDBC drivers. The only cost is a pair of parens, assuming you’d have a try-catch-else in place anyways.
As stated in the Oracle Tutorial, multiple AutoCloseable objects declared together will be closed in reverse order, just as we would want.
Tip: The try-with-resources syntax allows an optional semicolon on the last declared resource item. I include the semicolon as a habit because it reads well to my eye, is consistent, and facilitates cut-and-paste editing. I include it on your PreparedStatement s2 line.
public void doQueries() throws MyException{
// First try-with-resources.
try ( Connection con = DriverManager.getConnection( dataSource ) ;
PreparedStatement s1 = con.prepareStatement( updateSqlQuery ) ;
PreparedStatement s2 = con.prepareStatement( selectSqlQuery ) ;
) {
… Set parameters of PreparedStatements, etc.
s1.executeUpdate() ;
// Second try-with-resources, nested within first.
try (
ResultSet rs = s2.executeQuery() ;
) {
… process ResultSet
} catch ( SQLException e2 ) {
… handle exception related to ResultSet.
}
} catch ( SQLException e ) {
… handle exception related to Connection or PreparedStatements.
}
}
I suppose there is a more elegant syntax for this kind of work that might be invented in a future programming language. But for now, we have try-with-resources, and I do use it happily. While try-with-resources is not perfectly elegant, it is a big improvement over the older syntax.
By the way, Oracle recommends using a DataSource implementation for getting connections rather than the DriverManager approach seen in your code. Using DataSource throughout your code makes it easier to switch drivers or switch to a connection pool. See if your JDBC driver provides an implementation of DataSource.
Update: Java 9
Now in Java 9 you can initialize the resources before the try-with-resources. See this article. This flexibility may be useful in some scenarios.
The fun thing about JDBC code is that you're coding to a spec where it's not always clear how compliant your implementation is. There are a lot of different databases and drivers and some drivers are better-behaved than others. That tends to make people err on the side of caution, recommending things like closing everything explicitly. You could be ok with closing only the connection here. Closing the resultSet just to be on the safe side is hard to argue with. You don't indicate what database or driver you're using here, i wouldn't want to hardcode in assumptions about the driver that might not be valid for some implementation.
Closing things in sequence does leave you open to problems where an exception can get thrown and cause some of the closes to be skipped. You're right to be concerned about that.
Be aware this is a toy example. Most real code uses a connection pool, where calling the close method doesn't actually close the connection, instead it returns the connection to the pool. So resources may not get closed once you use a pool. If you want to change this code to use a connection pool then you'll have to go back and close the statements at least.
Also if you're objecting to the verbosity of this, the answer to that is to hide the code in reusable utilities that use strategies, resultSet mappers, prepared statement setters, etc. This has all been done before, of course; you'll be on the road to reinventing Spring JDBC.
Speaking of which: Spring JDBC closes everything explicitly (probably because it needs to work with as many drivers as possible, and doesn't want to cause problems due to some driver's not being well-behaved).
This is what I find to be the best solution for handling resources like JDBC. This method provides an immutable function, by leveraging final variables, and only declaring and assigning those variables if they are needed, it is very CPU efficient, and guarantees in all cases, that all resources that are assigned and opened are closed regardless of the state of exceptions. The technique you are using leaves gaps that can result in resource leaks if not carefully implemented to address all scenarios. This technique does not allow for a resource leak provided the pattern is always followed:
1) assign resource
2) try
3) use resource
4) finally close resource
public void doQueries() throws MyException {
try {
final Connection con = DriverManager.getConnection(dataSource);
try {
final PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
try {
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
} finally {
try { s1.close(); } catch (SQLException e) {}
}
final PreparedStatement s2 = con.prepareStatement(selectSqlQuery);
try {
// Set the parameters of the PreparedStatements and maybe do other things
final ResultSet rs = s2.executeQuery();
try {
// Do something with rs
} finally {
try { rs.close(); } catch (SQLException e) {}
}
} finally {
try { s2.close(); } catch (SQLException e) {}
}
} finally {
try { con.close(); } catch (SQLException e) {}
}
} catch (SQLException e) {
throw new MyException(e);
}
}
With Java 7, you can leverage the new try -with-resources to simplify this even more: The new try -with-resources follows the above logic flow, in that it will guarantee all resources include in the with resources block that are assigned get closed. any exception thrown in the with resources block will the thrown, but those assigned resources will still be closed. This code is much simplified and looks like this:
public void doQueries() throws MyException {
try (
final Connection con = DriverManager.getConnection(dataSource);
final PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
final PreparedStatement s2 = con.prepareStatement(selectSqlQuery);
final ResultSet rs = s2.executeQuery()) {
s1.executeUpdate();
// Do something with rs
} catch (SQLException e) {
throw new MyException(e);
}
}
[EDIT]: moved rs assignment into the resources block to show the simplest implementation. In practice, this simple solution does not really work, as this is not efficient. A connection should be reused, since establishing the connection is a very costly operation. Additionally, this simple example does not assign query parameters to the prepared statement. Care should be taken to handle these scenarios, as the the resource block should only include assignment statements. To depict this, I have also added another example
public void doQueries() throws MyException {
final String updateSqlQuery = "select ##servername";
final String selecSqlQuery = "select * from mytable where col1 = ? and col2 > ?";
final Object[] queryParams = {"somevalue", 1};
try (final Connection con = DriverManager.getConnection(dataSource);
final PreparedStatement s1 = newPreparedStatement(con, updateSqlQuery);
final PreparedStatement s2 = newPreparedStatement(con, selectSqlQuery, queryParams);
final ResultSet rs = s2.executeQuery()) {
s1.executeUpdate();
while (!rs.next()) {
// do something with the db record.
}
} catch (SQLException e) {
throw new MyException(e);
}
}
private static PreparedStatement newPreparedStatement(Connection con, String sql, Object... args) throws SQLException
{
final PreparedStatement stmt = con.prepareStatement(sql);
for (int i = 0; i < args.length; i++)
stmt.setObject(i, args[i]);
return stmt;
}
This is indeed the primary motivation for try-with-resources. See the Java tutorials as reference. Your professor is out-of-date. If you want to deal with the result set issue you can always enclose it in another try-with-resources statement.
You could make a util class to handle closing of these resources. i.e
FYI i just ignored SQLExceptions from trying to close resources in the util class, but you could as verywell log or collect and throw them once you are done closing the resources in the collection depending on your needs
public class DBUtil {
public static void closeConnections(Connection ...connections){
if(connections != null ){
for(Connection conn : connections){
if(conn != null){
try {
conn.close();
} catch (SQLException ignored) {
//ignored
}
}
}
}
}
public static void closeResultSets(ResultSet ...resultSets){
if(resultSets != null ){
for(ResultSet rs: resultSets){
if(rs != null){
try {
rs.close();
} catch (SQLException ignored) {
//ignored
}
}
}
}
}
public static void closeStatements(Statement ...statements){
if(statements != null){
for(Statement statement : statements){
if(statement != null){
try {
statement.close();
} catch (SQLException ignored) {
//ignored
}
}
}
}
}
}
and then just call it from you method:
public void doQueries() throws MyException {
Connection con = null;
try {
con = DriverManager.getConnection(dataSource);
PreparedStatement s1 = null;
PreparedStatement s2 = null;
try {
s1 = con.prepareStatement(updateSqlQuery);
s2 = con.prepareStatement(selectSqlQuery);
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
ResultSet rs = null;
try {
rs = s2.executeQuery();
} finally {
DBUtil.closeResultSets(rs);
}
} finally {
DBUtil.closeStatements(s2, s1);
}
} catch (SQLException e) {
throw new MyException(e);
} finally {
DBUtil.closeConnections(con);
}
}
I prefer to let Java auto-close. So I do something like this when I have to set values for ResultSet.
try (Connection conn = DB.getConn();
PreparedStatement ps = conn.prepareStatement("SELECT * FROM x WHERE y = ?")
) {
ps.setString(1, "yValue");
try(ResultSet rs = ps.executeQuery()) {
while(rs.next()) {
...
}
}
} catch (SQLException e) {
e.printStackTrace(e);
...
}

Should We put Connection in 1 method & PreparedStatement in a seperated method (Java)?

Here is my problem, I need to select data, but the data may be a lot so need to select the total results as well, so i need to call PreparedStatement twice for the same fields. I don't want to repeatedly write the same code twice, so I want put PreparedStatement into a different method. See ex:
public Order getOrders(){
Connection myCon = null;
PreparedStatement preparedStmt=null;
try{
myCon =getUnusedConnection();
String sql="select * from order where name=? ....... limit 0,3";
preparedStmt=myCon.prepareStatement(sql);
getOrderPreparedStatement(name,....);
ResultSet results=preparedStmt.executeQuery();
int rowCount=0;
while(results.next()){
......
rowCount++;
}
if(rowCount==3){
String sql2="select count(*) from Order where name=?....";
preparedStmt=myCon.prepareStatement(sql);
getOrderPreparedStatement(name,....);
ResultSet results2=preparedStmt.executeQuery();
if(results2){
int totalRow=....;
}
}
}
catch (SQLException ex) {
while (ex != null) {
System.out.println ("SQL Exception: " +
ex.getMessage ());
ex = ex.getNextException ();
}
}catch (java.lang.Exception e) {
System.out.println("***ERROR-->" + e.toString());
}
finally {
closeStatement(preparedStmt);
releaseConnection(myCon);
}
return null;
}
public void getOrderPreparedStatement(PreparedStatement preparedStmt, String name....)
{
try{
preparedStmt.setString(name);
... a lot of set field here....
}
catch (SQLException ex) {
while (ex != null) {
System.out.println ("SQL Exception: " +
ex.getMessage ());
ex = ex.getNextException ();
}
}catch (java.lang.Exception e) {
System.out.println("***ERROR-->" + e.toString());
}
finally {
closeStatement(preparedStmt); // do i need to close Statement in finally here
}
}
Is it a good practice to put Connection in 1 method & PreparedStatement in a seperated method. If it is ok to do that then "do i need to closeStatement in finally in getOrderPreparedStatement method?"
Or can u suggest a better solution?
Although it is definitely a good idea to move the code for repeated tasks into a method, you need to be very careful when deciding how much code to reuse.
Specifically, in your example you should not attempt to close the statement in the finally clause, because the statement that you prepare would be unusable outside the getOrderPreparedStatement.
One thing that you could do differently is dropping the exception-handling code from the method. This would keep the logic inside the method cleaner, so your readers would have easier time understanding your intentions. This would also reduce code duplication, because currently the code inside the catch (SQLException ex) block is identical.

delete sql not deleting

I'm trying to delete an event from my table. However I can't seem to get it to work.
My SQL statement is:
public void deleteEvent(String eventName){
String query = "DELETE FROM `Event` WHERE `eventName` ='"+eventName+"' LIMIT 1";
db.update(query);
System.out.println (query);
}
Using MySQL db
Try using the following :
String query = "DELETE FROM `Event` WHERE `eventName` ='"+eventName+"' LIMIT 1";
try {
Connection con = getConnection();
Statement s = con.createStatement();
s.execute(query);
} catch (Exception ex) {
ex.printStackTrace();
}
You have to code your getConnection() method to return a valid Database Connection.
I would suggest using Statement.executeUpdate method, since it returns an integer. So after performing this delete query you will also have information if you really deleted any records (in this case you would expect this method to return 1, since you are using LIMIT=1). I would also suggest closing Statement as soon as you don't need it, here is skeleton implementation:
private void performDelete(Connection conn, String deleteQuery, int expectedResult) throws SQLException {
Statement stmt = conn.createStatement();
int result = -1;
try {
result = stmt.executeUpdate(deleteQuery);
if(result != expectedResult) {
//Here you can check the result. Perhaps you don't need this part
throw new IllegalStateException("Develete query did not return expected value");
}
} catch(SQLException e) {
//Good practice if you use loggers - log it here and rethrow upper.
//Or perhaps you don't need to bother in upper layer if the operation
//was successful or not - in such case, just log it and thats it.
throw e;
} finally {
//This should be always used in conjunction with ReultSets.
//It is not 100% necessary here, but it will not hurt
stmt.close();
}
}

Categories