CS_Servlet

Page 1

8. Case Study: Data System Client Application, Applets Server Applications Servlets Databases


System Goals

Develop a system for managing large numbers of double-precision data values. – Create – Store – Display


Chart Data System Data generation Client

1

Data viewer Client

Data viewer Client

3

Browser: pure HTML

Java application

Browser: 4 Java applet

RMI

http 2

RMI

5 Java Application

Java Servlet

JDBC

JDBC RDMS Web Server

Middleware / Web Server


Database Schema extra

chart id: Integer value: Double label: Char[10]

✦ ✦ ✦ ✦ ✦

maxID: Integer id

va lu e

1 2 3… … … 11,497

la b e l 0.75 "A B C " 0.5 "H a lf" … … 0.785 "S in e "

Two simple tables. id is primary key for chart table. Data values are double-precision. Each value has an associated label. Only one row in extra table.

maxID 11,497


Sample Programs Servlet

3-Tier Applet/Application


Sample Programs ✦

ChartServlet - data generation client that uses JDBC to insert data into database. ChartApp - data display client. Can be run as applet or as stand-alone application. ServerApp - middleware that uses JDBC to query database. Relational Databases – InstantDB 100% Pure Java relational database. – Sybase SQL Anywhere 5.0.


9. Case Study: Data Input Servlet Servlets Databases


Objectives ✦

Be able to find performance bottlenecks in a servlet. Be able to more efficiently insert data into a SQL database. – use JDBC prepared statements. – use JDBC transactions.


Chart Data System Data generation Client

1

Browser: pure HTML

http 2 Java Servlet

JDBC RDMS Web Server


Database Schema chart id: Integer value: Double label: Char[10]

✦ ✦ ✦ ✦ ✦

id

va lu e

1 2 3… … … 11,497

la b e l 0.75 "A B C " 0.5 "H a lf" … … 0.785 "S in e "

extra maxID: Integer

Two simple tables. id is primary key for chart table. Data values are double-precision. Each value has an associated label. Only one row in extra table.

maxID 11,497


ChartServlet Sample Program


"chart.html" Calls Servlet <FORM ACTION="http://northptpc:8080/servlet/chart" METHOD="POST" ENCTYPE="application/x-www-form-urlencoded"> <H1>Add Chart Data</H1> Number of data points to add: <INPUT TYPE="TEXT" NAME="number" SIZE="7" MAXLENGTH="7"></H3> <INPUT TYPE="RADIO" NAME="RadioGroup" VALUE="random"> Random</P> <P><INPUT TYPE="RADIO" NAME="RadioGroup" VALUE="sine"> Sine</P> <P><INPUT TYPE="RADIO" NAME="RadioGroup" VALUE="half"> 0.5</P> <INPUT TYPE="SUBMIT" NAME="Submit" VALUE="Submit"></H3> </FORM>

✦ ✦

Calls servlet named "chart" when Submit button is pushed. Servlet gets values of named parameters.


chartServlet.properties File servlet.chart.code=ChartServlet servlet.chart.initArgs=\ driver=jdbc.idbDriver,\ url=jdbc:idb:d:\\+Java\\idb3_00\\ChartData2\\sample.prp,\ user=dba,\ pw=sql

✦ ✦

First line maps "chart" name used in HTML file to Java class name. initArgs is used to pass arguments to the servlet. – like parameters in HTML applet tag.


Servlet: Put Data Into DB HttpServlet

ChartServlet* fDriver fURL fUser fPassword fConnection fStart fStop kMaxIDQuery fMaxIDQueryStmt kID kValue kLabel kInsert fInsertStmt init destroy displayInitParameters doPost getMaxID fillRandom fillSine fillHalf prepareStatements openDBConnection

SingleThreadModel

init() and doPost() called when Submit button pressed. Connects to database and inserts data.


ChartServlet Methods public class ChartServlet extends HttpServlet implements SingleThreadModel { public void init(ServletConfig config); public void destroy(); public void doPost(HttpServletRequest req, HttpServletResponse res); protected void openDBConnection(); protected void prepareStatements(); protected void displayInitParameters(); protected int getMaxID(); protected void fillRandom(); protected void fillSine(); protected void fillHalf(); }


ChartServlet Variables public class ChartServlet extends HttpServlet implements SingleThreadModel { private String fDriver; private String fURL; private String fUser; private String fPassword; private Connection fConnection; private int fStart; private int fStop; private PreparedStatement fMaxIDQueryStmt; private PreparedStatement fInsertStmt; private final static String kInsert = "INSERT INTO chart VALUES(?,?,?)"; private final static String kMaxIDQuery = "SELECT maxID FROM extra"; }


ChartServlet.init() Method public void init(ServletConfig config) throws ServletException { super.init(config); fDriver = getInitParameter("driver"); fURL = getInitParameter("url"); fUser = getInitParameter("user"); fPassword = getInitParameter("pw"); try { openDBConnection(); prepareStatements(); fStart = getMaxID(); } catch (Exception e) {e.printStackTrace();} }


doPost() Action public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { fStop = fStart + Integer.parseInt(req.getParameter("number")); String fillMethod = req.getParameter("RadioGroup"); try { if (fillMethod.equals("random")) fillRandom(); else if (fillMethod.equals("sine")) fillSine(); else if (fillMethod.equals("half")) fillHalf(); updateMaxID(); ‌ // response stuff next slide } catch (SQLException e) {e.printStackTrace();} }


Inserting Data into Database protected void fillRandom() throws SQLException { Statement stmt = fConnection.createStatement(); for (int i = fStart; i<= fStop; i++) { String cmd = "INSERT INTO chart " + "VALUES ( " + i + "," + Math.random() + ", 'rdm' )"; stmt.executeUpdate(cmd); } stmt.close(); }

✦ ✦

Simplest way to do it. May not be the fastest.


doPost() Response public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ... res.setContentType("text/html"); PrintWriter toClient = res.getWriter(); toClient.println("<html>"); toClient.println( "<title>Data Modified!</title>"); toClient.println( "Num data points: " + getMaxID()); toClient.println("</html>"); toClient.close(); ...


Using ServletRunner call setJini :: enables servlet stack tracing SET JAVA_COMPCMD=STA(CKTRACE) SET sDir=d:\Samples\13_ChartServlet SET root=d:\Samples\13_ChartServlet SET propertiesFile= d:\Samples\13_ChartServlet\chartServlet.properties %servletDir%\bin\servletrunner -d %sDir% -r %root% -s %propertiesFile%

âœŚ

Starts servletRunner.


Performance OK? ✦

✦ ✦

Relational databases – Sybase SQL Anywhere 5.0. ◆ Sun's JDBC-ODBC bridge driver. ◆ Does not like JDK 1.2.2 HotSpot! – InstantDB 3.0. ◆ Own Java driver. ◆ Only one JVM at a time. Windows 95; 266 MHz Pentium; 128 MB RAM. Up to 20000 rows of data used.


Find Bottlenecks Рюд

OptimizeIt script:

call setjini SET OPTIT_LIB=d:\OptimizeIt30\lib\optit.jar; SET JSDK_LIB=d:\jsdk2.0\lib\jsdk.jar; SET IDB_LIB=d:\sample\idb3_00\classes\idb.jar SET CLASSPATH =%CLASSPATH%;%OPTIT_LIB%;%JSDK_LIB%;%IDB_LIB% SET OPTIT_PATH=d:\OptimizeIt30\lib SET SERVLET_DIR=d:\sample\PerfSamples_10-09-99\09b_ChartServlet java -Xrunoii -Djava.compiler=NONE -Xnoclassgc -classpath "%CLASSPATH%" intuitive.audit.Audit -pause -dmp -dllpath "%OPTIT_PATH%" sun.servlet.http.HttpServer -d %SERVLET_DIR% -r %SERVLET_DIR% -s %SERVLET_DIR%\chartServletIDB.properties


Using OptimizeIt for Servlet ✦ ✦

✦ ✦

Run the servlet script Attatch the servlet into OptimizeIt program

Start CPU profiling. Submit Add Chart Data information.


Do Exercise 9


OptimizeIt CPU Profiler

✦ ✦ ✦

Only 2% of time spent with maxID - good. 63% of time spent in fillHalf(). May need a faster database to reduce this significantly. These tests had client and server on same machine. Bad idea.


Fix Bottlenecks ✦

Use Prepared Statements. – Database can precompile parameterized statements. Best for repeated statements. Use JDBC Transactions for groups of statements. – By default, each executeUpdate() statement is treated as a separate transaction. ◆ Database may lock records. ◆ Commit is called each time. – Better to group all updates into a single JDBC transaction.


Create Prepared Statements private final static String kInsert = "INSERT INTO chart VALUES(?,?,?)"; private final static String kMaxIDQuery = "SELECT max ID FROM extra"; //-------------------------------------------protected void prepareStatements() throws SQLException { fInsertStmt = fConnection.prepareStatement(kInsert); fMaxIDQueryStmt = fConnection.prepareStatement(kMaxIDQuery); }

âœŚ

Create precompiled SQL statements for later execution.


Using PreparedStatment protected void fillHalf() throws SQLException { for (int i = fStart; i<= fStop; i++) { fInsertStmt.setInt(kID, i); fInsertStmt.setDouble(kValue, 0.5); fInsertStmt.setString(kLabel, "half"); fInsertStmt.executeUpdate(); } }

âœŚ

Faster than regular statement if execute it many times.


Use JDBC Transaction: try protected void fillSine() { try { fConnection.setAutoCommit(false); for (int i = fStart; i<= fStop; i++) { fInsertStmt.setInt(kID, i); fInsertStmt.setDouble(kValue, Math.sin(i)); fInsertStmt.setString(kLabel, "sine"); fInsertStmt.executeUpdate(); } fConnection.commit(); } catch // see next slide }

âœŚ

All or nothing. May be the fastest.


Use JDBC Transaction: catch protected void fillSine() { try { // see previous slide } catch (SQLException e) { try { fConnection.rollback(); e.printStackTrace(); } catch (SQLException ex) { ex.printStackTrace(); } } finally { try { fConnection.setAutoCommit(true); } catch (Exception ex2) { ex2.printStackTrace(); } } }


Performance Comparison M e th o d / D B

sq lA n y 2 0 0 (se c) ID B 5 0 0 (se c) 1 .4 8 .0 S ta te m e nt (ra ndo m ) 0 .9 6 .0 P re pS tm t (ha lf) 0 .5 3 .0 P re pS tm t + T ra ns (sine ) âœŚ

âœŚ

PreparedStatement faster than Statement. PreparedStatement + transactions is best in this example.


Summary ✦ ✦

Can use OptimizeIt or JProbe to profile servlet. Use PreparedStatement for repeated commands. Use Transactions for grouped commands.


Notes


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.