Links

Lists

Latest Updates

Ruby On Rails List
Python list
Advanced Java
The JavaScript List
Apache Users
Full Disclosure
Linux Security

Search the archives!


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Urgent help on database server.


  • From: tonyp@xxxxxxxxx (Tony Pelton)
  • Subject: Urgent help on database server.
  • Date: Thu, 30 Mar 2000 10:45:07 -0800

Hi Nabeel,

First off, IMHO ... if your Java is not using JNI ... then a GPF in the
java.exe is a bug in the JVM ... though you are using the JdbcOdbc bridge
... which could have bugs in it as I mention later.

Having said that ... I would mention the following things about your example
...

1. Starting a Thread for the QueryServer itself seems like a no-op and a
waste of a thread in this case.

2. I am in the camp that believes that 'extending' Thread is not the way to
create a threaded object. i.e. IMHO, Connect() should implment runnable.

3. A 'backlog' of 1000 inbound attempts to connect seems high to me ... and
I would lower that _way_ down ... I think on Solaris the default is like 5.

4. To point 2 above, in your connect constructor I would do absolutely as
_little_ work as possible ... i.e. if it were me, I would simply set the
'socket' object you got from the accept call ... and I would do all of the
other stuff you are doing in the Connect constructor ... in the run() method
on Connect. This will allow the thread running you accept() call to get back
to accept()ing ASAP.

5. clean up those catch() blocks in the try where you are actually running
the query. If you are getting errors in there ... you won't know it.

6. This is purely my opinion ... and I have seen this discussion on here
before. This design basically allows this server to run rampant with thread
counts. There is no 'limiter' in here that allows the code to control the
number of users actually doing runnable work. It could be because this is
just a first pass rough draft ... but you may want to give that some
thought.

7. The JdbcOdbc bridge in Java is probably not the best way to try and build
a strong DB server. Further ... even if the JdbcOdbc bridge is stable ...
the ODBC driver that it is using on your behalf may not be stable ... and/or
it may have thread bugs in it. This could even very well be the _real_
source of the GPF.

You may want to look into the 'Dr. Watson' log to see if you can get more
info.

Tony

> -----Original Message-----
> From: Nabeel Mukhtar Siddiqui [mailto:nabeelmukhtar@xxxxxxxxx]
> Sent: Thursday, March 30, 2000 7:13 AM
> To: Advanced Java Mailing List; RealHowTo Mailing List
> Subject: Urgent help on database server.
> Importance: High
> 
> 
> I am not very experienced in Java programming and hence I am facing a
> problem in implementing a simple mulithreaded database 
> server. The server
> connects to client side applets through sockets, receives the 
> query from the
> clients and returns the resultset in string format.This 
> happens after every
> 5 seconds. I also tried to make the server multithreaded so 
> that multiple
> clients can be simultaneously serviced. This server runs on a 
> Windows NT
> machine (JDK 1.2). It works fine in the night time when very 
> few clients
> connect to the server however in the office hours when the 
> no. of clients
> reaches as high as 400, the server shuts down and the OS displays the
> message that application java.exe has caused an access 
> violation at the
> memory address _______. This is very annoying and critical 
> for me. I also
> haven't worked on Windows NT. What may be the cause of the 
> error? Below is
> the partial code of the server (the rest is irrelavent). 
> Please give me
> suggestions, pointers etc on the cause of the problem. Also I 
> have tried to
> make the server multithreaded. Is it working so? Is the 
> architecture good
> enough to support multiple (almost 1000) clients 
> simultaneously? How can I
> improve on it? If any one needs more specific details please 
> inform me, but
> please do help me. It is very urgent.
> Thank you.
> 
> import java.io.*;
> import java.net.*;
> import java.sql.*;
> 
> public class QueryServer implements Runnable {
>     private Socket   connection;
> 
>     public void run() {
>  ServerSocket server;
>  int      counter = 1;
> 
>  try {
> 
>      // Step 1: Create a ServerSocket.
>      server = new ServerSocket(5000, 1000);
> 
>      while (true) {
> 
>   // Step 2: Wait for a connection.
>   connection = server.accept();
> 
>   Connect cc = new Connect(connection);
> 
>      }
>  } catch (IOException e) {
>      e.printStackTrace();
>  }
>     }
> 
>     public static void main(String args[]) {
>  new Thread(new QueryServer()).start();
>     }
> 
>     protected void finalize() {
>  try {
>      connection.close();
>  } catch (IOException ioe) {
>      ioe.printStackTrace();
>  }
>     }
> 
> }
> 
> class Connect extends Thread {
>     private final String FIELD_SEPARATOR = "#";
>     private final String COLUMN_SEPARATOR = "|";
>     private final String ROW_SEPARATOR = "$";
>     private String       query;
>     private ResultSet    resultSet;
>     private String       stringResultSet;
>     Socket   client;
>     DataOutputStream     output;
>     DataInputStream      input;
> 
>     public Connect(Socket s) {    // constructor
>  client = s;
> 
>  try {
>      input = new DataInputStream(client.getInputStream());
>      output = new DataOutputStream(client.getOutputStream());
>  } catch (IOException e) {
>      try {
>   client.close();
>      } catch (IOException ex) {
>   System.out.println("Error while getting socket streams.."
>        + ex);
>      }
> 
>      return;
>  }
> 
>  this.start();
>     }
> 
>     public void run() {
>  try {
> 
>      // get a request and parse it.
>      while (true) {
>   query = input.readUTF();
>   System.out.println(query);
>   accessDataBase(query);
>   System.out.println(stringResultSet);
>   output.writeUTF(stringResultSet);
>      }
>  } catch (IOException e) {
>      System.out.println("I/O error " + e);
>  } catch (Exception ex) {
>      System.out.println("Exception: " + ex);
>  }
>     }
> 
>     private synchronized void accessDataBase(String query) {
>  String url = "jdbc:odbc:sysdsn";
> 
>  try {
> 
>      // Load the jdbc-odbc bridge driver
>      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
> 
>      Connection con = DriverManager.getConnection(url, "", "");
>      Statement  stmt = con.createStatement();
> 
>      resultSet = stmt.executeQuery(query);
> 
>      convertResultSetToStream();
> 
>      // Close the statement
>      stmt.close();
> 
>      // Close the connection
>      con.close();
>  } catch (SQLException ex) {}
>  catch (java.lang.Exception ex) {}
>     }
> 
>     private void convertResultSetToStream() throws SQLException {
>  StringBuffer      theResultSet = new StringBuffer();
> 
>  // Get the ResultSetMetaData.  This will be used for
>  // the column headings
>  ResultSetMetaData rsmd = resultSet.getMetaData();
> 
>  // Get the number of columns in the result set
>  int    numCols = rsmd.getColumnCount();
> 
>  // append the column labels first.
>  for (int column = 0; column < numCols; column++) {
>      theResultSet.append(rsmd.getColumnLabel(column + 1));
>      theResultSet.append(COLUMN_SEPARATOR);
>  }
> 
>  theResultSet.append(FIELD_SEPARATOR);
> 
>  // now append the table values.
>  while (resultSet.next()) {
>      for (int i = 1; i <= numCols; i++) {
>   theResultSet.append(resultSet.getString(i));
>   theResultSet.append(COLUMN_SEPARATOR);
>      }
> 
>      theResultSet.append(ROW_SEPARATOR);
>  }
> 
>  stringResultSet = theResultSet.toString();
>     }
> 
>     protected void finalize() {
>  try {
>      client.close();
>  } catch (IOException ioe) {
>      ioe.printStackTrace();
>  }
>     }
> }
> 
> 
> 
> ---
> To unsubscribe, mail advanced-java-unsubscribe@xxxxxxxxxxxxxxxx
> To get help, mail advanced-java-help@xxxxxxxxxxxxxxxx
> 

---
To unsubscribe, mail advanced-java-unsubscribe@xxxxxxxxxxxxxxxx
To get help, mail advanced-java-help@xxxxxxxxxxxxxxxx