Re: Multi-user problem

2002-02-07 Thread Shannon Chen

Member variables are shared by different users coz
only doPost/doGet is called when servlet gets request.
The simultaneous access of the same data by multiple
users...so make sure you have the user sensitive data
declared in doPost/doGet ( also the DB connection !!)




--- [EMAIL PROTECTED] wrote:
> I developed a system for reviewing scanned image
> quality.
> The system worked like a champ during development
> and on launch day.
> The next day, we went from 1 user to 2.
> The system is 100% intolerant of simultaneous
> requests.
> Anytime the second user makes a request before the
> first user's request is fulfilled, output stops and
> both requests are not fulfilled; The system is
> 'hung'.  
> Restarting Apache HTTP server resumes normal
> operation.
> The situation is easily reproducable.  Any ideas?
> 
> Note: After looking at my pseudo-code at the bottom,
> it may help to know that occasionally when this
> happens, 
> my servlet outputs this error to the Tomcat Console
> window:
> 'Login Parameters not found'
> 
> Since I'm using post requests, I cannot see the
> parameters, but this error indicates that the
> parameters are 
> incompletely sent or not sent at all when this
> occurs.  
> And it's not just the parameters, but the whole
> request to Tomcat, and maybe its response.
> When login parameters are not sent, the servlet will
> show a "bad login" page.  It doesn't happen in this
> case.
> 
> My best conclusion is that when this NEXTIMAGE
> servlet is run twice at once, it causes Apache to
> stop talking to tomcat properly.
> 
> 
> 
> Apache 1.3 is a service on Windows 2000 running
> Tomcat 4 on the same server, with SQL server 2000
> SP1 on the same server.  
> My system has 2 servlets, AUDREPORT and NEXTIMAGE. 
> AUDREPORT is run once per user at login.  
> NEXTIMAGE is called repeatedly (say 1000 to 3000
> times per workshift per user).
> Database connections are made through ODBC with the
> JDBC:ODBC:DSN bridge using the
> sun.jdbc.odbc.JdbcOdbcDriver driver.  I used a
> SYSTEM DSN.
> If it makes any difference, The machine has MDAC 2.6
> SP1, BDE 5.1, Winzip 8, Pegasus ImagN' 4.0 imaging
> components, 
> a Custom Delphi 6 database app and VNC installed on
> it and is logged in as Administrator.
> 
> 
> I'm not at home with Apache error log entries, but I
> see a lot of these:
> (of the following, I think packet 6 errors are most
> prevalent):
> Invalid Packet 2 followed by numerous
> 'communitcation interrupted' messages, between 1 and
> 10 of them, all within one second.
> Invalid Packet 6 followed by numerous
> 'communitcation interrupted' messages, between 1 and
> 10 of them, all within one second.
> Invalid Packet 200 followed by numerous
> 'communitcation interrupted' messages, same as
> above.. 
> forcing termination of child #0 (handle 520)//(
> <-- this handle is always 520 and always child #0.)
> 
> It's worth noting that NONE of the above errors
> occurred on launch day (when I was sure there was
> only 1 user).
> 
> 
> 
> The users follow this work flow:
> 
> 1) Enter name/password at Login page (which is plain
> HTML with a form that is directed to servlet
> AUDREPORT.
> 
> 2) A report is generated, reflecting how many images
> are total, done, and undone.  On the page is a
> submit button which calls servlet NEXTIMAGE.
> 
> 3) NEXTIMAGE generates a page with an image and some
> checkboxes on a form which is redirected to the
> NEXTIMAGE servlet.  
> So, 99% of the time, all users are accessing the
> same servlet.
> 
> 4) The loop is broken when the user has viewed the
> last available image, and the users are sent back to
> the login page.
> 
> Workers are viewing images from the same pool, and
> obviously both call the same servlet on the same
> server repeatedly.  So, nextimage is the servlet
> that is running when the problem occurs.
> 
> 
> 
> The NEXTIMAGE servlet looks something like this
> pseudo-code:
> public static void login(...){ Tell database user is
> logged in. }
> public static void logout(...) {Tell database user
> is logged out.}
> public static void updateaccesstime(...) {Tell
> Database I made a request}
> public void doPost(HttpServletRequest request,
> HttpServletResponse response) {
> }
> userid=request.getparameter("userid");
> password=request.getparameter("password");
> if lastaccess was too long ago {logout; return;}
> if (userid is present and password is present) {
>   if (userid/password is in database) {
> updateaccesstime(userid,password) }
>   else { System.err.println('Login Parameters not
> found'); Send badloginpage to client; return;}
> }
> 
> 
> if (submit_action=="logout") logout;
> if (submit_action="get image") {
> Get details about previous image (if any) from
> request.getParameters(...) and update database with
> the info.
> { //Get next image
> Get the name of the next available image and reserve
> it.
> // Generate HTML for Image Evaluation page, placing
> image name in parameters of ActiveX image control
> embedded in the pa

Re: Multi-user problem

2002-02-06 Thread Jason Koeninger

On Wed, 06 Feb 2002 19:55:40 -0500, [EMAIL PROTECTED] wrote:

>I'm not sure I understand what you mean by "keeping class data", so I've copied the 3 
>methods here.  In an attempt to answer your question...

Is "con" a class variable?  For instance, is it declared something like this:

public class MyServlet extends HttpServlet {

private Connection con;
.
.
.
};


If it is, multiple users will step on each others' connections.  Only one instance 
of the servlet is created to serve multiple requests.  If "con" is declared local 
to the service method, then it's not a problem.

Best Regards,

Jason Koeninger
J&J Computer Consulting
http://www.jjcc.com



>1) None of my servlets use multithreading.. I'm new to Java and haven't learned that 
>yet.
>2) A database connection is opened as soon as necessary in the servlet and I expect 
>it to remain available until the servlet closes.  I do not expect it to be available 
>across multiple 
instances.
>3) The database connection is forced closed at the end of the servlet.
>
>Here's the code for the 3 routines plus the database connect and disconnect (please 
>don't laugh.. this is the result of a very steep learning curve and a bunch of 
>troubleshooting).  As 
you see, the login/out methods expect an existing statement (which is bound to a 
connection) as a parameter:
>
>
>//---
>public static void login(String userid, Statement st) {
>String s="";
>System.err.println("Login");
>try {
>s=
>"use sqaa "+
>"update emps "+
>"set loggedin=1, "+
>"lastaccess='"+thelper.getcurtime()+"' "+
>"where userid='"+userid+"' ";
>st.executeUpdate(s);
>} catch (Exception exc) {
>System.err.println("Error during login().");
>System.err.println("  "+exc.getClass().getName());
>System.err.println("  "+exc.getMessage());
>System.err.println(s);
>return;
>}
>}
>//
>public static void logout(int userrecordid, String userid, Statement st) {
>String s="";
>System.err.println("Logout");
>try {
>System.err.println("..logging out");
>s=
>"use sqaa "+
>"update emps "+
>"set loggedin=0 "+
>"where userid='"+userid+"' ";
>st.executeUpdate(s);
>
>System.err.println("..cancelling reservations for "+userrecordid+", 
>"+userid);
>s=
>"use sqaa "+
>"update images "+
>"set auditorid=null, auditorstatus='U' "+
>"where auditorid="+userrecordid+" "+
>"and auditorstatus='X'";
>st.executeUpdate(s);
>
>System.err.println("Done logging out.");
>
>} catch (Exception exc) {
>System.err.println("Error during logout.");
>System.err.println("  "+exc.getClass().getName());
>System.err.println("  "+exc.getMessage());
>System.err.println(s);
>return;
>}
>}
>//
>public static void updateaccesstime(String userid, Statement st) {
>String s="";
>System.err.println("Updateaccesstime");
>s=
>"use sqaa "+
>"update emps "+
>"set lastaccess = '"+thelper.getcurtime()+"' "+
>"where userid='"+userid+"' ";
>try {
>st.executeUpdate(s);
>
>} catch (Exception exc) {
>System.err.println("Error during updateaccesstime().");
>System.err.println("  "+exc.getClass().getName());
>System.err.println("  "+exc.getMessage());
>System.err.println(s);
>return;
>}
>}
>
>
>//Open JDBC Connection (This occurs right after getting the POST parameters):
>try{
>Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
>con = DriverManager.getConnection("jdbc:odbc:sqaa","philg","");
>query = con.createStatement();
>}
>catch (Exception exc) {
>System.err.println("Error creating JDBC connection.");
>System.err.println(exc.getClass().getName());
>System.err.println(exc.getMessage());
>thelper.fileServe(out,"c:/html/except.html");
>return;
>}
>
>//Close database connection (this is the last thing done).
>try{
>con.close();
>} catch (Exception exc) {
>System.err.println("Error closing database.");
>System.err.println(exc.getClass().getName());
>System.err.println(exc.getMessage());
>thelper.fileServe(out,"c:/html/except.html");
>return;
>}
>
>-- 
>
>
>
>
>_

Re: Multi-user problem

2002-02-06 Thread August Detlefsen

In the past I have had good luck with the SQL Server JDBC drivers from
iNet software: 

http://www.inetsoftware.de/English/Produkte/JDBC_Overview/ms.htm

Though I wouldn't really recommend SQL Server for anything if you do
not have to use it...


--- [EMAIL PROTECTED] wrote:
> "Tom Drake" <[EMAIL PROTECTED]> wrote:
> 
> As suggested, I will try to find a different driver (instead of the
> odbc/jdbc bridge) to connect to MSSQL2k.
> In the meantime.. I reflect on your other thoughts...
> 
> >>See my comments below.
> >... snip ...
> >|
> >| The NEXTIMAGE servlet looks something like this pseudo-code:
> >| public static void login(...){ Tell database user is logged in. }
> >| public static void logout(...) {Tell database user is logged out.}
> >| public static void updateaccesstime(...) {Tell Database I made a
> request}
> >Are the above functions keeping class data
> >(such as a connection to your database)?
> >
> >If a 'login' request gets a new database connection,
> >then any other thread that is using
> >the original connection will break.
> 
> Do other instances of the servlet count as other threads?
> 
> I'm not sure I understand what you mean by "keeping class data", so
> I've copied the 3 methods here.  In an attempt to answer your
> question...
> 1) None of my servlets use multithreading.. I'm new to Java and
> haven't learned that yet.
> 2) A database connection is opened as soon as necessary in the
> servlet and I expect it to remain available until the servlet closes.
>  I do not expect it to be available across multiple instances.
> 3) The database connection is forced closed at the end of the
> servlet.
> 
> Here's the code for the 3 routines plus the database connect and
> disconnect (please don't laugh.. this is the result of a very steep
> learning curve and a bunch of troubleshooting).  As you see, the
> login/out methods expect an existing statement (which is bound to a
> connection) as a parameter:
> 
> 
> //---
> public static void login(String userid, Statement st) {
> String s="";
> System.err.println("Login");
> try {
> s=
> "use sqaa "+
> "update emps "+
> "set loggedin=1, "+
> "lastaccess='"+thelper.getcurtime()+"' "+
> "where userid='"+userid+"' ";
> st.executeUpdate(s);
> } catch (Exception exc) {
> System.err.println("Error during login().");
> System.err.println("  "+exc.getClass().getName());
> System.err.println("  "+exc.getMessage());
> System.err.println(s);
> return;
> }
> }
> //
> public static void logout(int userrecordid, String userid,
> Statement st) {
> String s="";
> System.err.println("Logout");
> try {
> System.err.println("..logging out");
> s=
> "use sqaa "+
> "update emps "+
> "set loggedin=0 "+
> "where userid='"+userid+"' ";
> st.executeUpdate(s);
> 
> System.err.println("..cancelling reservations for
> "+userrecordid+", "+userid);
> s=
> "use sqaa "+
> "update images "+
> "set auditorid=null, auditorstatus='U' "+
> "where auditorid="+userrecordid+" "+
> "and auditorstatus='X'";
> st.executeUpdate(s);
> 
> System.err.println("Done logging out.");
> 
> } catch (Exception exc) {
> System.err.println("Error during logout.");
> System.err.println("  "+exc.getClass().getName());
> System.err.println("  "+exc.getMessage());
> System.err.println(s);
> return;
> }
> }
> //
> public static void updateaccesstime(String userid, Statement st)
> {
> String s="";
> System.err.println("Updateaccesstime");
> s=
> "use sqaa "+
> "update emps "+
> "set lastaccess = '"+thelper.getcurtime()+"' "+
> "where userid='"+userid+"' ";
> try {
> st.executeUpdate(s);
> 
> } catch (Exception exc) {
> System.err.println("Error during updateaccesstime().");
> System.err.println("  "+exc.getClass().getName());
> System.err.println("  "+exc.getMessage());
> System.err.println(s);
> return;
> }
> }
> 
> 
> //Open JDBC Connection (This occurs right after getting the
> POST parameters):
> try{
> Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
> con =
> DriverManager.getConnection("jdbc:odbc:sqaa","philg","");
> query = con.createStatement();
> }
> catch (Exception exc) {
> System.err.printl

Re: Multi-user problem

2002-02-06 Thread Tom Drake

See my comments below.

- Original Message -
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Wednesday, February 06, 2002 3:23 PM
Subject: Multi-user problem


... snip ...
| Apache 1.3 is a service on Windows 2000 running Tomcat 4 on the same
server, with SQL server 2000 SP1 on the same server.
| My system has 2 servlets, AUDREPORT and NEXTIMAGE.  AUDREPORT is run once
per user at login.
| NEXTIMAGE is called repeatedly (say 1000 to 3000 times per workshift per
user).
| Database connections are made through ODBC with the JDBC:ODBC:DSN bridge
using the sun.jdbc.odbc.JdbcOdbcDriver driver.  I used a SYSTEM DSN.


The JDBC/ODBC bridge is notoriously bad and not thread safe.
This could be the root of your problems. If you are using
MS-ACCESS, I think you're probably stuck with it and will
have to synchronize around your database calls. I'm pretty
sure there is a 'real' JDBC driver available for SQL Server.


... snip ...
|
| The NEXTIMAGE servlet looks something like this pseudo-code:
| public static void login(...){ Tell database user is logged in. }
| public static void logout(...) {Tell database user is logged out.}
| public static void updateaccesstime(...) {Tell Database I made a request}

Are the above functions keeping class data
(such as a connection to your database)?

If a 'login' request gets a new database connection,
then any other thread that is using
the original connection will break.




--
To unsubscribe:   
For additional commands: 
Troubles with the list: