Skip to Main Content

Java EE (Java Enterprise Edition) General Discussion

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Totally frustrated...

843836Apr 3 2005 — edited Apr 4 2005
Hi...

I really need some help. I've put countless hours of reading and testing into an effort to try and resolve a concurrency (thread safety) problem in a web application I'm trying to develop. This message will be somewhat long because I've put together a skinnied down sample of what I'm doing.

Problem:

Using 2 different PC's, I display the index.jsp page. On PC 1 I click on the User 1 Info link and at the same exact time, I click the User 2 Info link on PC 2. The result, if timed properly, displays the same info on both PC's. It should never do that.

Environment:

Windows XP
Apache 2
Tomcat 5
MySql 4.0.21
MySqlJ Connector 3.1.7
Ethernet Network
Apache/Tomcat/MySql running on PC1.

Although this the application I'm developing is more complex than this model, I have successfully recreated this problem condition, even using this simple model.

The following code contains the basic structure of what I'm doing. I've also included a MySQL dump to allow anybody that might be seeing this to see the database record structure.

Please, please, please give me some pointers. I've tried many, many scenarios to eliminate the problem, but other than just making this a single threaded application, which I don't want to do, I just don't see why this doesn't work. (Also... please understand that I don't have the hard coded URL's in my actual application. This was just for quickly throwing something together that would not be too long.)

index.jsp
<%@ page session="true" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Simple Demo</title>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  </head>
  
  <body>
	<table width="50%" border="0" cellpadding="0" cellspacing="0">
		<tr>
			<td width="100%" align="center">
				Simple Demo
			</td>
		</tr>
		<tr>
			<td width="100%" align="center">
				<a href="http://192.168.64.102:8080/simpleDemo/servlet/SimpleCtl?tc=0&uid=1">Click here for User1 info.</a>
			</td>
		</tr>
		<tr>
			<td width="100%" align="center">
				<a href="http://192.168.64.102:8080/simpleDemo/servlet/SimpleCtl?tc=0&uid=2">Click here for User2 info.</a>
			</td>
		</tr>
	</table>
  </body>
</html>
SimpleForm.jsp
<%@ page session="true" %>
<jsp:useBean id="sb" class="simpledemo.SimpleBean" scope="request" />

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>
    <title>Simple Form</title>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>

<body>

<table width="100%" cellpadding="5" cellspacing="0">
	<tr>
		<td width="25%">
			User ID:
		</td>
		<td width="75%">
			<jsp:getProperty name="sb" property="userID" />
		</td>
	</tr>
	<tr>
		<td width="25%">
			User First Name:
		</td>
		<td width="75%">
			<jsp:getProperty name="sb" property="userFirstName" />
		</td>
	</tr>
	<tr>
		<td width="25%">
			User Last Name:
		</td>
		<td width="75%">
			<jsp:getProperty name="sb" property="userLastName" />
		</td>
	</tr>
	<tr>
		<td width="25%">
			User Email:
		</td>
		<td width="75%">
			<jsp:getProperty name="sb" property="userEmail" />
		</td>
	</tr>
</table>
					
</body>

</html>
SimpleCtl.java
package simpledemo;

import java.io.* ;

import javax.servlet.* ;
import javax.servlet.http.* ;

import simpledemo.SimpleBean;

public class SimpleCtl extends HttpServlet  {

	public void init() throws ServletException
	{
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance() ;
		}
		catch (Exception e) {
			e.printStackTrace() ;
		}
	}
	
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		doPost(request, response) ;
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		RequestDispatcher rd = null ;
		HttpSession session = request.getSession() ;
		
		try
		{
			int nAction = Integer.parseInt(request.getParameter("tc")) ;
			long lUserID = Long.parseLong(request.getParameter("uid")) ;
			
			switch (nAction)
			{
				case 0:
					SimpleBean sb = new SimpleBean() ;
					
					synchronized(sb)
					{
						sb.getUserRecord(request, lUserID) ;
						session.setAttribute("sb",sb) ;
					}
					
					rd = request.getRequestDispatcher("/SimpleForm.jsp") ;
					
					break ;
				default: // Display Login Page
					rd = request.getRequestDispatcher("/index.jsp") ;
				break ;
			}
		} catch (Exception e)
		{
			rd = request.getRequestDispatcher("/index.jsp") ;
		}

		if (rd == null)
		{
			sendResponse(response, "Unable to get RequestDispatcher") ;
		}
		else
		{
			response.addHeader("Content-Type", "text/html; charset=ISO-8859-1");
			rd.forward(request, response) ;
		}
	}

	private void sendResponse(HttpServletResponse response, String strMessage) throws IOException
	{
		response.setContentType("text/html") ;

    	PrintWriter pw = response.getWriter() ;

		pw.println(strMessage) ;
	}

}
ConnectionBean.java
package simpledemo;

import java.sql.* ;
import javax.servlet.http.* ;

public class ConnectionBean implements HttpSessionBindingListener
{

	private Connection con = null ;
	
	public ConnectionBean(Connection dbConnection)
	{
		this.con = dbConnection ;
	}
	
	public Connection getCon()
	{
		return(con) ;
	}
	
	public void valueBound(HttpSessionBindingEvent e)
	{
		// Do nothing on binding a session
	}
	
	public void valueUnbound(HttpSessionBindingEvent e)
	{
		try
		{
			if (con != null)
			{
				con.close() ;
			}
		}
		catch (SQLException s)
		{
			s.printStackTrace() ;
		}
	}
}
SimpleBean.java
package simpledemo;

import java.io.* ;
import java.sql.* ;
import javax.servlet.http.* ;
import simpledemo.ConnectionBean;

public class SimpleBean implements Serializable {

	private String strHost = "jdbc:mysql://localhost/simpledb?user=simpleuser&password=simplepw" ;

	// Private properties to represent User record structure
	
	private static long userID ;
	private static String userLastName ;
	private static String userFirstName ;
	private static String userEmail ;

	public SimpleBean()
	{
		super() ;
	}
	
	public long getUserID() {
		return(userID) ;
	}		
		
	public String getUserLastName() {
		return(userLastName) ;
	}		
		
	public String getUserFirstName() {
		return(userFirstName) ;
	}		
		
	public String getUserEmail() {
		return(userEmail) ;
	}		
		
	public void getUserRecord(HttpServletRequest request, long lUserID)
	{
		HttpSession s = request.getSession() ;

		Connection c = getDBConnection(request) ;
		
		try {
			String strSqlCmd = "select * from user_master " ;
			strSqlCmd += "where UserID = "+lUserID ;
			Statement sqlCmd1 = c.createStatement() ;
			ResultSet rs = sqlCmd1.executeQuery(strSqlCmd) ;
			
			if (rs.next()) {
				userID = rs.getLong("UserID") ;
				userLastName = rs.getString("UserLastName") ;
				userFirstName = rs.getString("UserFirstName") ;
				userEmail = rs.getString("UserEmail") ;
			}
		}
		catch (SQLException e) {
			e.printStackTrace() ;
		}
	}
	
	public Connection getDBConnection(HttpServletRequest request)
	{
		Connection c ;
		HttpSession s = request.getSession() ;

		synchronized(s)
		{
			ConnectionBean cb = (ConnectionBean) s.getAttribute("cb") ;
			
			if (cb == null)
			{
				try
				{
					cb = new ConnectionBean(DriverManager.getConnection(strHost)) ;
					s.setAttribute("cb",cb) ;
				}
				catch (SQLException e)
				{
					e.printStackTrace() ;
				}
			}
			
			c = cb.getCon() ;
		}
		
		return(c) ;
	}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <servlet>
    <description>SimpleCtl Servlet Requests</description>
    <display-name>SimpleCtl Servlet Requests</display-name>
    <servlet-name>SimpleCtl</servlet-name>
    <servlet-class>simpledemo.SimpleCtl</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>SimpleCtl</servlet-name>
    <url-pattern>/servlet/SimpleCtl</url-pattern>
  </servlet-mapping>

</web-app>
MySql Dump:
-- phpMyAdmin SQL Dump
-- version 2.6.0-pl2
-- http://www.phpmyadmin.net
-- 
-- Host: localhost
-- Generation Time: Apr 03, 2005 at 12:32 PM
-- Server version: 4.0.21
-- PHP Version: 4.3.9
-- 
-- Database: `simpledb`
-- 

-- --------------------------------------------------------

-- 
-- Table structure for table `user_master`
-- 

CREATE TABLE `user_master` (
  `UserID` bigint(20) NOT NULL auto_increment,
  `CompanyID` bigint(20) NOT NULL default '0',
  `UserLastName` varchar(25) NOT NULL default '',
  `UserFirstName` varchar(15) NOT NULL default '',
  `UserEmail` varchar(50) NOT NULL default '',
  `UserTimeZone` varchar(50) NOT NULL default '',
  `LoginID` varchar(10) NOT NULL default '',
  `LoginPW` varchar(10) NOT NULL default '',
  PRIMARY KEY  (`UserID`),
  KEY `UserLastName` (`UserLastName`)
) TYPE=InnoDB COMMENT='User Master' AUTO_INCREMENT=5 ;

-- 
-- Dumping data for table `user_master`
-- 

INSERT INTO `user_master` VALUES (1, 1, 'Pacific', 'Test', 'test_pst@localhost.localdomain.com', 'US/Pacific', 'test_pst', 'test_pst');
INSERT INTO `user_master` VALUES (2, 1, 'Mountain', 'Test', 'test_mst@localhost.localdomain.com', 'US/Mountain', 'test_mst', 'test_mst');
INSERT INTO `user_master` VALUES (3, 1, 'Central', 'Test', 'test_cst@localhost.localdomain.com', 'US/Central', 'test_cst', 'test_cst');
INSERT INTO `user_master` VALUES (4, 1, 'Eastern', 'Test', 'test_est@localhost.localdomain.com', 'US/Eastern', 'test_est', 'test_est');
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 2 2005
Added on Apr 3 2005
4 comments
182 views