在servlet中如何实现多线程或同步的问题!!!( 
4、因为数据库中查询的记录较多,在servlet中增加的分页显示的功能。
5、每次我连续点击下一页时,出现当前页与上一页显示在一起的情况。
请问如何解决。。

解决方案 »

  1.   

    我使用的是oracle,请问如何实现事务隔离级设为不允许幻影读取。
      

  2.   

    把你的Servlet贴出来看看!这好像更数据库的事务没什么联系!!呵呵,或许我太菜了,不知道吧!
      

  3.   

    public class CommonQuery extends HttpServlet {
        static final private String CONTENT_TYPE = "text/html; charset=GBK";    private  Connection conn = null;
        //数据库中的时间
        private java.sql.Date dbServerDate = null;    private  AddValueToHashtable hashtableValue = null;
        //口音的哈希表
        private Hashtable hashAccent = new Hashtable();
        //专长的哈希表
        private Hashtable hashSpeciality = new Hashtable();
        //民族的哈希表
        private Hashtable hashNation = new Hashtable();
        //性别的哈希表
        private Hashtable hashGender = new Hashtable();
        //****************显示页面的变量*************    //Process the HTTP Get request
        public  void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        response.setContentType(CONTENT_TYPE);
            PrintWriter out = response.getWriter();
           // request.setCharacterEncoding("GBK");        DBConnectionJNDI dbconnection = new DBConnectionJNDI();        try{            this.conn = dbconnection.createConnection();
                //建立AddValueToHashtable类的对象
                hashtableValue = new AddValueToHashtable(this.conn);
                hashGender = hashtableValue.setHashGender();
                hashNation = hashtableValue.setHashNation();
                hashSpeciality = hashtableValue.setHashSpeciality();
                hashAccent = hashtableValue.setHashAccent();
            }
            catch(Exception e){
                e.printStackTrace();
            }        //照片链接中需要的sql语句
            String url = "";
            String sql = "";
            CombinSQL combinsql= new CombinSQL();        //**********************取得待显示页码***********
            int pageSize = 0;//一页显示的记录数,从页面中提取
            int pageWait = 0;//待显示页码        String strPage = null;
            strPage = request.getParameter("page");        try{
                StringBuffer buffer = new StringBuffer(100);//存放jsp页面的变量
                buffer.delete(0,buffer.capacity());
                String printInfo = new String();
                //显示页面
                synchronized(printInfo){
                    
                    printInfo = printMessage(sql,url,pageSize,pageWait,isAgeQuery,buffer);
                    out.println(printInfo);
                }
                buffer.delete(0,buffer.length());
                dbconnection.closeConnection();
                this.conn.close();
            }
            catch(SQLException e){
                e.printStackTrace() ;
            }
        }
         //显示页面的头
        private  void printHeader(int pageWait,int pageSize,String url,StringBuffer buffer){
            buffer.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>" +
                          "<html><head><title>Untitled Document</title>"+
                          "<link href='css1.css' rel='stylesheet' type='text/css'>" +
                          "<meta http-equiv='Content-Type' content='text/html; charset=gb2312'>" +
                          "<script language=javascript>  " +
                          " function makevisible(cur,which){"+
                          " if (which==0) "+
                          " cur.filters.alpha.opacity=100; "+
                          " else  cur.filters.alpha.opacity=60;}");
           
        }    //显示页面的实体
        private   void printForm(String isAgeQuery,StringBuffer buffer){
            buffer.append("<tr><td colspan='2' bgcolor='#52769F'><table width='100%' border='0' cellpadding='0' cellspacing='1' bordercolor='#FFFFFF' bgcolor='#6F8EB0' class='text'> " +
                          " <tr bgcolor='#52769F'> " +
                          " <td align='center' nowrap><font color='#FFFFFF'>姓名</font></td> "+
                          "<td align='center' nowrap><font color='#FFFFFF'>身份证号</font></td>"+
                          "<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>性别</font></td>");
            if(isAgeQuery.equalsIgnoreCase("v1")){
                buffer.append( "<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>出生日期</font></td>");
            }
            else if (isAgeQuery.equalsIgnoreCase("v2")){
                buffer.append( "<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>年龄</font></td>");
            }        buffer.append("<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>户籍地编码</font></td>"+
                          "<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>户籍地描述</font></td>"+
                          "<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>民族</font></td>"+
                          "<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>口音</font></td>"+
                          "<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>专长</font></td>"+
                          "<td align='center' nowrap bgcolor='#52769F'><font color='#FFFFFF'>详细信息连接</font></td>"+
                          "</tr>");
        }
      

  4.   

    //从数据库中查询信息并显示
        private  String printMessage(String sql,String url,int pageSize,int pageWait,String isAgeQuery,StringBuffer buffer) throws SQLException{
            String returnValue = new String() ;//返回的页面字符串            Statement ss =null;
                ResultSet  result =null;
                int rowCount ;//记录总数
                int pageCount ;//总页数
                if (conn == null){
                    returnValue ="不能获得数据库连接。";
                    return returnValue;
                }            try{
                    ss=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
                    result = ss.executeQuery(sql);                //********************根据记录集获得页面总数等信息********
                    result.last();
                    rowCount = result.getRow();//获得记录总数
                    //计算总页数
                    pageCount = (rowCount + pageSize-1)/pageSize;
                    //调整待显示的页面
                    if(pageWait > pageCount)
                    {
                        pageWait = pageCount;
                    }
                    //*********************************************************
                    if (pageCount < 1)
                    {
                        errorPage errPage = new errorPage();
                        returnValue = errPage.printErrorPage();
                        return returnValue;
                    }
                    //print header
                    buffer.delete(0,buffer.capacity());
                    printHeader(pageWait,pageSize,url,buffer);
                    //print form
                    printForm(isAgeQuery,buffer);                //*****将记录指针定位到待显示页的第一条记录上********
                    result.absolute((pageWait - 1) * pageSize +1);
                    //显示数据
                    int i =0;
                    //专长
                    String speciality = null;
                    //民族
                    String nation = null;
                    //性别
                    String gender = null;
                    //口音
                    String accent = null;                while(i < pageSize && !result.isAfterLast()){
                        buffer.append("<tr bgcolor='#52769F'>");
                        buffer.append("<td>" + result.getString("criminal_name") + "</td>");
                        if(result.getString("identity_id")==null){
                            buffer.append("<td>&nbsp;</td>");
                        }
                        else{
                            buffer.append("<td>" + result.getString("identity_id") + "</td>");
                        }                    //性别
                        buffer.append("<td bgcolor='#52769F'>");
                        if(result.getString("gender_code") == null){
                            gender = "&nbsp;";
                        }
                        else{
                            gender =(String)hashGender.get(result.getString("gender_code").trim());
                        }
                        buffer.append(gender + "</td>");
                        //民族
                        buffer.append("<td bgcolor='#52769F'>");
                        if (result.getString("nation_code") ==null){
                            nation = "&nbsp;";
                        }
                        else{
                            nation = (String)hashNation.get(result.getString("nation_code").trim());
                        }
                        buffer.append(nation + "</td>");                    //口音
                        buffer.append("<td bgcolor='#52769F'>");
                        if(result.getString("accent_code") == null){
                            accent = "&nbsp;";
                        }
                        else{
                            accent = (String)hashAccent.get(result.getString("accent_code").trim());
                        }                    buffer.append(accent + "</td>");
                        //专长
                        buffer.append("<td bgcolor='#52769F'>");
                        if (result.getString("speciality1_code") == null){
                            speciality = "&nbsp;";
                        }
                        else{
                            speciality =(String)hashSpeciality.get(result.getString("speciality1_code").trim());
                        }                    buffer.append(speciality+ "</td>");                    buffer.append("<td bgcolor='#52769F'>");
                        buffer.append("<a href='DetailWeb/PeopleDetail.jsp?criminal_no=" + result.getString("criminal_no") +  "'><font color='#00FF00'>详细信息链接</font></a></td>");
                        buffer.append("</tr>");
                        result.next();
                        i++;
                    }
                    buffer.append("</table></td></tr>");                //print page
                    printPage(pageWait,pageCount,url,buffer);
                    //Print bottom
                    printBottom(buffer);
                    //convert stringbuffer to string
                    returnValue =buffer.toString();
                    //get stringbuffer capacity
                    int bb = buffer.capacity();
                    //delete stringbuffer
                    buffer = buffer.delete(0,bb);
                }
                catch(Exception e){
                    e.printStackTrace();
                }
                result.close();
                ss.close() ;
                System.out.println(returnValue);
                return returnValue;    }
        //显示页面的底
        private  void printBottom(StringBuffer buffer){
            buffer.append("<tr><td width='60%' align='right' bgcolor='#52769F'><input name='image2' type='image' style='filter:alpha(opacity=100)'" +
                          "onMouseOver='makevisible(this,1)' onMouseOut='makevisible(this,0)' onclick='window.close()' src='images/close.gif' width='127' height='28'></td>"+
                          "<td align='right' bgcolor='#52769F'>&nbsp;</td></tr>"+
                          "<tr bgcolor='#44637F'><td colspan='2'>&nbsp;</td></tr></table></td></tr></table></td>"+
                          "<td background='images/2.gif'><img src='images/1.gif' width='4' height='4'></td></tr>" +
                          "<tr><td height='4' colspan='2' background='images/3.gif'><img src='images/1.gif'></td></tr>" +
                          "</table></td></tr></table></td></tr></table></form></body></html>");
        }    //显示分页信息
        private  void printPage(int pageWait,int pageCount,String url,StringBuffer buffer){
            buffer.append("<tr><td colspan='5' align='right' bgcolor='#52769F'>");
            buffer.append("<font color='#FFFFFF'>第" + pageWait + "页&nbsp;&nbsp;  共" + pageCount + "页&nbsp;&nbsp;</font>");        if (pageCount ==1){
                buffer.append("<font color='#FFFFFF'>上 一 页&nbsp;&nbsp;");
                buffer.append("下 一 页&nbsp;&nbsp;");
            }
            else if (pageCount >1 && pageWait <pageCount){
                if (pageWait ==1){
                    buffer.append("上一页&nbsp;&nbsp;");
                }
                else{
                    buffer.append("<a href ='/commonquery?page=" + (pageWait-1)  + "&" + url.trim() + "'><font color='#00FF00'>上 一 页</font></a>&nbsp;&nbsp;");
                }
                buffer.append("<a href ='/commonquery?page=" + (pageWait+1) +  "&" + url.trim() + "'><font color='#00FF00'>下 一 页</font></a>&nbsp;&nbsp;");
            }
            else if(pageCount >1 && pageWait == pageCount){
                buffer.append("<a href ='/commonquery?page=" + (pageWait-1) +  "&" + url.trim() + "'><font color='#00FF00'>上 一 页</font></a>&nbsp;&nbsp;");
                buffer.append("下一页&nbsp;&nbsp;");
            }        buffer.append("<font color='#FFFFFF'>转到</font><input type='text' name='page' size='2' value='" + pageWait + "' onKeyPress='return checkit(event)'><font color='#FFFFFF'>页</font>" +
                          " <img style='filter:alpha(opacity=100)' onMouseOver='makevisible(this,1)' " +
                          " onMouseOut='makevisible(this,0)'  src='images/go
      

  5.   

    不允许幻影读取就是在访问数据库的时候,如果其他用户正在插入一个新的数据正好与你的查询条件相同,这样你再次查询,新的数据就出现了。
    你在分页程序在下一页时又执行了一次查询,这时要有新数据出现就会也查询出来,这样的隔离级的效率很低。如果你是这个意思,可以试试。事务隔离级设为
    conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)
      

  6.   

    你的查询SQL语句是否设置了偏移量?SQL怎么写的
      

  7.   

    我们的数据库中在查询的时候,一般不会有新的数据插入。
    conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)
    方法我已经试过,不成功。
    sql语句是最简单的select * from table where  条件。
    我现在的问题是:点击下一页时又执行了一次查询,然后根据当前页码计算记录集的游标,然后将游标在加十(每页显示10条记录)。如果我不是连续点击下一页,则不出现当前页与上一页显示在一起的情况。正常情况是:我点击下一页并暂停2秒钟以上,在点击下一页程序运行都正确。
    不知道是否与ie的刷新有关。
      

  8.   

    我觉得不是数据库的问题,也不是线程的问题,synchronized我认为没有必要
    ,你可以试一下response 的这几个方法setBufferSize(int),reset(),getBufferSize(), flushBuffer(), isCommitted()。在最后加上flushBuffer()或在前面加上reset()。