正确的servlet / jdbc设计和并发问题

时间:2014-01-08 05:50:44

标签: multithreading servlets jdbc

关于正确的设计和并发,我想问几个问题。在这个例子中,我创建了一个简单的应用程序,它通过servlet获取参数并添加到数据库中。所以这个过程是这样的。 1)将名字/姓氏发送给servlet 2)Servlet调用PersonDao.createPerson(firstname,lastname)。

涉及的课程...... PersonDao的(接口) PersonDaoImpl(具体类) AbstractDao(抽象类) PersonController(Servlet的)

如果这是一个设计正确,连接汇集的代码,我想知道您的所有意见。这种静态创建数据源是否正确?你会改变AbstractDao类中可能造成并发问题的任何内容吗?

public interface PersonDao {
    public void createPerson(String firstname, String lastname);
}

_

public class PersonDaoImpl extends AbstractDao implements PersonDao {

@Override
public void createPerson(String firstname, String lastname) {

    String query = " insert into persons values (?,?) ";

    Connection connection = null;
    PreparedStatement ps = null;
    try {
        connection = getConnection();
        ps = connection.prepareStatement(query);
        ps.setString(1, firstname);
        ps.setString(2, lastname);
        ps.executeUpdate();

    } catch (SQLException e) {
        System.out.println(e.toString());
    } finally {
        close(connection, ps, null);
    }

}
}

_

public abstract class AbstractDao {

protected static DataSource dataSource;

static{
    try {
        dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/MyDataSource");

    } catch (NamingException e) { 
        throw new ExceptionInInitializerError("jdbc/MyDataSource' not found in JNDI");
    }
}

protected Connection getConnection() throws SQLException {
    return dataSource.getConnection();
}

protected void close(Connection connection) {
    close(connection, null, null);
}

protected void close(Connection connection, Statement ps) {
    close(connection, ps, null);
}

protected void close(Connection connection, Statement ps, ResultSet rs) {

    try {
        if (rs != null)
            rs.close();

        if (ps != null)
            ps.close();

        if (connection != null)
            connection.close();

    } catch (SQLException e) {
        e.printStackTrace();
    }

}

}

-

@WebServlet("/PersonController")
public class PersonController extends HttpServlet {
private static final long serialVersionUID = 1L;

public PersonController() {
    super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String firstname = request.getParameter("firstname");
    String lastname = request.getParameter("lastname");

    PersonDao personDao = new PersonDaoImpl();
    personDao.createPerson(firstname, lastname);

}

}

我的另一个问题是这里是否存在并发问题,特别是在servlet中。想象一下1000个请求同时命中servlet。令我担心的是PersonDaoImpl 1000个不同的线程,每个线程都有自己的堆栈。所以PersonDaoImpl有1000个不同的实例。如果我们去AbstractDao,它会在数据源上调用getConnection。

所以问题就是...... getConnection()是否会引发并发问题? 1000个不同的请求可以从上面的代码对数据源对象构成威胁吗? 如果私有PersonDao personDao = new PersonDaoImpl()作为servlet中的实例,该怎么办?现在发生了什么?

我真正感到困惑的是当PersonDaoImpl被实例化时doGet中发生了什么。有人可以给我一个演练。我的问题的要点是,我在那里的代码是否是线程安全的。

1 个答案:

答案 0 :(得分:0)

具有讽刺意味的是,我刚刚回答了10月份的一个问题。

See my answer here.