Some reader favorites:
EJB fundamentals and session beans
Create a scrollable virtual desktop in Swing
Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API
Imagine a railroad station operating in such a way that each passenger who buys a ticket immediately gets a train dedicated only to him! This modus operandi is absurd in real life, but is widely accepted in the world of Web application servers and data access applications. The conventional paradigm implies that each user request receives its own thread and database connection. Each user request requires an immediate dedicated trip to the database or other network resource. Obviously, there should be a smarter way of handling external traffic than buying extra hardware. Let's explore a simple but overlooked way of increasing your application's productivity.
In this article, we employ a new approach where each interaction with the database or network resource occurs on behalf of multiple users rather than only one, where negative effects of high concurrency like timeouts and deadlocks are greatly reduced, and where heavy traffic performance regression is almost negligible.
To be able use this approach—a paradigm I call Train—we must create an adequate environment for running our application and perform proof-of-concept tests.
To illustrate the advantage of the proposed architecture, we are going to build two simple, functionally equivalent servlets. Both deliver the same HTML pages with data retrieved from a sample database. Each servlet represents a different implementation—the conventional paradigm and the new one. To build our servlets, we need a Web application server, a database and a load-test runner. You are free to use your software of choice; my pieces are Tomcat 4, JMeter, and IBM'S DB2 Universal Database. Tomcat 4 and JMeter are open source applications and free. The choice of DB2 is just an attempt to imitate the commercial Web environment as closely as possible.
Assuming the name of your database is "trdata," let's create the necessary schema:
//schema.sql
connect to trdata;
create table trentry (ID integer not null , NAME char(25), DESCR varchar(128), views integer with default 0, constraint p_trentry primary key (ID));
The simple Java application PropSamples populates table trentry with 250,000 rows of random content:
//PropSamples.java
package train;
import java.util.*;
import java.sql.*;
public class PropSamples {
public static String GetString(int size, Random rand) {
StringBuffer strBuff = new StringBuffer();
for (int i = 0; i < size; i++) {
char b = (char) (rand.nextInt(25) + 65);
strBuff.append(b);
}
return strBuff.toString();
}
public void Process() throws SQLException {
String sqlString = "insert into trentry values(?,?,?,?)";
Connection connection = Util.getDBConnection();
PreparedStatement stmt = connection.prepareStatement(sqlString);
Random rand = new Random();
for (int i = 1; i <= 250000; i++) {
stmt.clearParameters();
stmt.setInt(1, i);
stmt.setString(2, GetString(25, rand));
stmt.setString(3, GetString(128, rand));
stmt.setInt(4, 0);
stmt.execute();
if (i%1000 == 0) {
connection.commit();
System.out.println(i + " rows committed");
}
}
}
public static void main(String[] args) throws SQLException{
PropSamples propSamples = new PropSamples();
propSamples.Process();
}
}
This code is nothing to write home about. Class Util (available in the source code, which is downloadable from Resources) contains DB2-related specifics that should change depending on the environment.
Here you go—the servlet at its best: each user request is serviced by a separate lightweight thread, database connections
could have been taken from the pool, there is clear separation between model and view, and so on. See our conventional ClassicServlet below:
// ClassicServlet.java
package train;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.sql.*;
public class ClassicServlet
extends HttpServlet {
int mEntryLength = 250000;
Random mRand;
public void init() throws ServletException {
mRand = new Random(System.currentTimeMillis());
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
PrintWriter out = response.getWriter();
Statement stmt = null;
Connection connection = null;
String name = "";
String descr = "";
int views = 0;
int id = 0;
boolean isError = false;
synchronized (mRand) {
id = mRand.nextInt(mEntryLength);
}
try {
connection = Util.getDBConnection();
stmt = connection.createStatement();
String sqlStr = "Select id, name, descr, views from trentry where id =" + id;
ResultSet rs = stmt.executeQuery(sqlStr);
while (rs.next()) { //retrieves data from from DB
name = rs.getString("NAME");
descr = rs.getString("DESCR");
id = rs.getInt("ID");
views = rs.getInt("VIEWS");
}
Statement stmtViews = connection.createStatement();
String sqlViewStr = "update trentry set views = views+1 where id =" + id;
stmtViews.executeUpdate(sqlViewStr); //updates number of the page views
}
catch (SQLException ex) {isError = true;}
finally {
try {
if (stmt != null) {
stmt.close();
}
if (connection != null) {
connection.commit();
connection.close();
}
}
catch (SQLException ex1) {isError = true;}
}
if (isError) {
out.println("<html>System error</html>");
}
else { //Delivers html page to browser
out.println("<html>");
out.println("<p>ID: " + id + "</p>");
out.println("<p>Name: " + name + "</p>");
out.println("<p>Description: " + descr + "</p>");
out.println("<p>Views: " + views + "</p>");
out.println("</body></html>");
}
}
}
I deployed the servlet, typed http://localhost:8080/train/classicservlet in my browser, and received the following page:
ID: 178866
Name: XEIRVYPSFTNRXYEWQWSKOOPES
Description: JBGPGKSMDQKVXVPJCXKIMWLEWJABSGBNTOYRXRKUMDBWOYOCIAKDWGGEBHKIFONGSRBIBJIHSBNGEYIO
RKGFOVWYXYXXJKUBBLVBSKOKLFCHIGRUGROKESIJQFERWJTV
Views: 0
Not much is happening here, but this is a fair imitation of many routine commands in the e-commerce world. A servlet extracts some meaningless data from the database, updates number of views, and spits out the result. Please note that we are generating random keys to retrieve random rows from the trentry table. A good database management system usually caches the data. As a result, a second select statement against the same entry in the table would execute much faster. Our trick with random keys will keep our data "cold" and our following performance measurements accurate.
| Subject | Replies |
Last post
|
|
By Odi |
1 |
04/27/08 04:29 AM
by Anonymous |
|
By OIeg Grytsyuk |
0 |
04/22/08 06:02 AM
by Anonymous |
|
By JavaWorld
|
13 |
04/17/08 02:06 PM
by Anonymous |
|
By testeras |
0 |
04/02/08 09:31 AM
by Anonymous |
|
By Peter Khler |
1 |
04/02/08 09:20 AM
by Anonymous |
|
By Anonymous |
1 |
04/02/08 09:20 AM
by Anonymous |
Free Download - 5 Minute Product Review. When slow equals Off: Manage the complexity of Web applications - Symphoniq
![]()
Free Download - 5 Minute Product Review. Realize the benefits of real user monitoring in less than an hour. - Symphoniq