Handling Read Timeout caused by network fluctuation - java

I am having a java application which reads the records(count of records to b read is configurable) from the sql 2008 database.
And process them and this is done in a infinite loop and only stops when application is stopped manually.
The issue im facing here is that the application stops fetching records from database when I get Read Time out error.
And I guess this is because of the network fluctuations.
The code for reading from the db is written in try catch block.so when the error occurs it gets logged but also stops.
I have no idea how to handle such situation and make the application run continuously in spite of the error.
Please let me know how can I handle the error such that my application continues to run.

While reading you should store the information on where you stopped and set the connection up again after it failed to continue.
Like this:
boolean programRuns = true; // set this to false at the end
public void doMyStuff() {
int myLastPosition = 0;
while(programRuns) {
try {
Connection con = /* open your connection */
String statement = /* your statement */ + "WHERE id > " + myLastPosition;
PreparedStatement pstmt = /* prepare your statement */
while(true) {
ResultSet rs = pstmt.executeQuery();
myLastPosition = rs.getInt("id");
/* do whatever you want with the result */
}
} catch (Exception ex) { /* handle the exception */ }
}
}

Related

Is it a good idea to close the JDBC connection in case of PG Listen/Notify polling?

We use connection pool in our application. While I understand that we should close and get connections as needed since we are using a connection pool. I implemented a cache update mechanism by receiving Postgres LISTEN notifications. The code is pretty much similar to the canonical example given by the documentation.
As you can see in the code, the query is initiated in the constructor and the connection is re used. This may pose problem when the connection is closed out of band due to any factor. One solution to this is to get the connection before every use, but as you can see the statement is only executed once in the constructor but still I can receive the notification in the polling. So if I get the connection every time, it will force me to re issue the statement for every iteration(after delay). I'm not sure if that's an expensive operation.
What is the middle ground here?
class Listener extends Thread
{
private Connection conn;
private org.postgresql.PGConnection pgconn;
Listener(Connection conn) throws SQLException
{
this.conn = conn;
this.pgconn = conn.unwrap(org.postgresql.PGConnection.class);
Statement stmt = conn.createStatement();
stmt.execute("LISTEN mymessage");
stmt.close();
}
public void run()
{
try
{
while (true)
{
org.postgresql.PGNotification notifications[] = pgconn.getNotifications();
if (notifications != null)
{
for (int i=0; i < notifications.length; i++){
//use notification
}
}
Thread.sleep(delay);
}
}
catch (SQLException sqle)
{
//handle
}
catch (InterruptedException ie)
{
//handle
}
}
}
In addition to this, there is also another similar document which had another query in run method as well in addition to constructor. I'm wondering if someone could enlighten me the purpose of another query within the method.
public void run() {
while (true) {
try {
//this query is additional to the one in the constructor
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 1");
rs.close();
stmt.close();
org.postgresql.PGNotification notifications[] = pgconn.getNotifications();
if (notifications != null) {
for (int i=0; i<notifications.length; i++) {
System.out.println("Got notification: " + notifications[i].getName());
}
}
// wait a while before checking again for new
// notifications
Thread.sleep(delay);
} catch (SQLException sqle) {
//handle
} catch (InterruptedException ie) {
//handle
}
}
}
I experimented closing the connection in every iteration(but without getting another one). That's still working. Perhaps that's due to unwrap that was done.
Stack:
Spring Boot, JPA, Hikari, Postgres JDBC Driver (not pgjdbc-ng)
The connection pool is the servant, not the master. Keep the connection for as long as you are using it to LISTEN on, i.e. ideally forever. If the connection ever does close, then you will miss whatever notices were sent while it was closed. So to keep the cache in good shape, you would need to discard the whole thing and start over. Obviously not something you would want to do on a regular basis, or what would be the point of having it in the first place?
The other doc you show is just an ancient version of the first one. The dummy query just before polling is there to poke the underlying socket code to make sure it has absorbed all the messages. This is no longer necessary. I don't know if it ever was necessary, it might have just been some cargo cult that found its way into the docs.
You would probably be better off with the blocking version of this code, by using getNotifications(0) and getting rid of sleep(delay). This will block until a notice becomes available, rather than waking up twice a second and consuming some (small) amount of resources before sleeping again. Also, once a notice does arrive it will be processed almost immediately, instead of waiting for what is left of a half-second timeout to expire (so, on average, about a quarter second).

android.os.on main thread exception

I am trying to connect to my sql DB on my sql server, using the below code.
But when I run it, the above error shows.
I have added the permissions line to the manifest, but still no luck.
Any advice will be appreciated!
Log.i("Android"," MySQL Connect Example.");
Connection conn = null;
try {
String driver = "net.sourceforge.jtds.jdbc.Driver";
Class.forName(driver).newInstance();
//test = com.microsoft.sqlserver.jdbc.SQLServerDriver.class;
String connString = "jdbc:jtds:sqlserver://server_ip_address :1433/DBNAME;encrypt=fasle;user=xxxxxxxxx;password=xxxxxxxx;instance=SQLEXPRESS;";
String username = "xxxxxx";
String password = "xxxxxxxxxx";
conn = DriverManager.getConnection(connString,username,password);
Log.w("Connection","open");
Statement stmt = conn.createStatement();
ResultSet reset = stmt.executeQuery("select * from TableName");
//Print the data to the console
while(reset.next()){
Log.w("Data:",reset.getString(3));
//Log.w("Data",reset.getString(2));
}
conn.close();
} catch (Exception e) {
Log.w("Error connection","" + e.getMessage());
}
NetworkOnMainThreadException: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
You should call sendfeedback method on asynctask then only above code will work. As webserver is taking lot of time to response main thread becomes unresponsive. To avoid it you should call it on another thread. Hence AsyncTask is better.
http://android-developers.blogspot.in/2009/05/painless-threading.html

connecting with Derby from within the java application

this program works fine when i connect the java db under the 'Services' tab in netbeans but when i try to open the executable jar file of the prog outside neatbeans it doesn't work at all. I want this java application to be accessible by multiple users as i wish to put it on the my local network so i figured that i need to connect to the Derby database in network mode....am i correct.?.....how should i fix this..?following is code snipet of my application
public void DoConnect() {
try {
/*
** Load the Derby driver.
** When the embedded Driver is used this action start the Derby engine.
** Catch an error and suggest a CLASSPATH problem
*/
Class.forName("org.apache.derby.jdbc.ClientDriver");
try {NetworkServerControl server = new NetworkServerControl();
server.start (null);}
catch(Exception e)
{
System.err.println(e.getMessage());
}
System.out.println(driver + " loaded. ");
} catch (java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
System.out.println("\n >>> Please check your CLASSPATH variable <<<\n");
}
try {
//CONNECT TO THE DATABASE
String host = "jdbc:derby://localhost:1527/Employee";
String uName = "admin";
String uPass = "admin";
//EXECUTE SQL QUERY AND LOAD RESULTSET
con = DriverManager.getConnection(host, uName, uPass);
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String SQL = "SELECT * FROM Workers";
rs = stmt.executeQuery(SQL);
//MOVE CURSOR TO FIRST RECORD AND GET DATA
rs.next();
int id_col = rs.getInt("ID");
String id = Integer.toString(id_col);
String first_name = rs.getString("First_Name");
String last_name = rs.getString("Last_Name");
String job = rs.getString("Job_Title");
//DISPLAY THE FISRT RECORD IN THE TEXT FIELD
textID.setText(id);
textFirstName.setText(first_name);
textLastName.setText(last_name);
textJobTitle.setText(job);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
IMHO it is bad practice to use a Derby database in network mode and to start the server in the same application. You combine all weaknesses of both world :
you cannot access the database from the outside (you server has to be local)
what happens if you server is allready running (if multiple executions on same node) ?
I think it works fine under Netbeans, because Netbeans is doing all the housekeeping for you : starting the server when you access to it via Netbeans interface, and closing it when closing Netbeans.
I think you should try the folowing :
start a server (manually) from outside of your application
remove the code for launching server from your app
(and do not forget to stop server when you have finished with it ...)
By the way I cannot understand what you mean by "not even starting" : if you start it from command line, you should have at least an error message ...
The way you've written the program there is no reason to meddle with the services tab. You should be able to just run (debug) the program directly in NB. Set a breakpoint, debug and step through it. When that works you can try to run from the command line.

JSF page freezes when is reloaded many times

I use this code to fetch data from database table.
public List<Dashboard> getDashboardList() throws SQLException {
if (ds == null) {
throw new SQLException("Can't get data source");
}
//get database connection
Connection con = ds.getConnection();
if (con == null) {
throw new SQLException("Can't get database connection");
}
PreparedStatement ps = con.prepareStatement(
"SELECT * from GLOBALSETTINGS");
//get customer data from database
ResultSet result = ps.executeQuery();
List<Dashboard> list = new ArrayList<Dashboard>();
while (result.next()) {
Dashboard cust = new Dashboard();
cust.setUser(result.getString("SessionTTL"));
cust.setPassword(result.getString("MAXACTIVEUSERS"));
//store all data into a List
list.add(cust);
}
return list;
}
This code is a part of a JSF page which is deployed on glassfish server. The problem is that when I reload the JSF page many times(around 8 times) the web page freezes. I suspect that the thread pool is fill and there is no space for new connections. How I can solve the problem? Close the connection when the query is finished or there is another way?
Best wishes
First of all: Yes you should close your connection when your done by explicitly calling the close() method. Closing a connection will release database resources.
UPDATE: And you should close the PreparedStatement as well (with close()). I would also recommend to handle SQLExceptions in your method and not throw it, since you need to make sure that your statement and connection are closed even if an exception occurs.
Something like this:
Connection connection = dataSource.getConnection();
try {
PreparedStatement statement = connection.prepareStatement();
try {
// Work with the statement
catch (SQLException e ) {
// Handle exceptions
} catch (SQLException e {
// Handle exceptions
} finally {
statement.close();
}
} finally {
connection.close();
}
Furthermore, you should not query the database in a bean field's getter method. Getters can be called several times during each request. The more elegant way would be to prepare the DashboardList in the constructor or #PostConstruct of your bean.

Will Database omit incoming request since it is busy?

In my application I have implemented a method to get favourits of particular user. If the user is a new one there will not be a entry in the table.If so I add default favourtis to the table. Code is shown below.
public String getUserFavourits(String username) {
String s = "SELECT FAVOURITS FROM USERFAVOURITS WHERE USERID='" +
username.trim() + "'";
String a = "";
Statement stm = null;
ResultSet reset = null;
DatabaseConnectionHandler handler = null;
Connection conn = null;
try {
handler = DatabaseConnectionHandler.getInstance();
conn = handler.getConnection();
stm = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
reset = stm.executeQuery(s);
if (reset.next()) {
a = reset.getString("FAVOURITS").toString();
}
reset.close();
stm.close();
}
catch (SQLException ex) {
ex.printStackTrace();
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
try {
handler.returnConnectionToPool(conn);
if (stm != null) {
stm.close();
}
if (reset != null) {
reset.close();
}
}catch (Exception ex) {
ex.printStackTrace();
}
}
if (a.equalsIgnoreCase("")) {
a = updateNewUserFav(username);
}
return a;
}
You can see that after the Finally block updateNewUserFav(username) method is use to insert default favourits in to table. Normally users are forced to change this in their first login.
My problem is many users have complain me about they hava lost their customized favourits and default has get loaded in their login. When I go through the code I notice that it can only happen if exception occured in the try block. When I debug code works fine. Is this can be coused at time when DB is busy?
Normally there are more than 1000 concurrent user in the system. Since it is real time application there will be huge number a of request comming to the Database(DB is Oracle).
Can some one pls explain.
Firstly, use jonearles suggestion about bind variables. If a lot of your code is like this, with 1000 concurrent users, I'd hate to think what performance is like.
Secondly, if it is busy then there is a chance of time-outs. As you say, if an exception is encountered then it falls back to the "updateNewUserFav"
Really, it should only call that if NO exception is raised.
If an exception is raised, the function should fail. The current code is similar to
"TURN THE IGNITION KEY TO START THE CAR"
"IF THERE IS A PROBLEM, RING GARAGE AND BOOK APPOINTMENT"
"PUT CAR INTO GEAR AND RELEASE HAND_BRAKE"
You really only want to release the hand-brake once the car has successfully started, otherwise you'll end up rolling down the hill until the sudden stop at the end (often involving an expensive CRUNCH sound).

Categories

Resources