I have a couple questions I would like to ask regarding correct design and concurrency. For the example, I created a simple application that takes parameters via servlet and adds to database. So the process is like so. 1) Send firstname/lastname to servlet 2) Servlet calls PersonDao.createPerson(firstname, lastname).
Classes involved... PersonDao(Interface) PersonDaoImpl(Concrete Class) AbstractDao(Abstract class) PersonController(Servlet)
I would like to know all your opinions if this is a correctly designed, connection-pooled, code. Is that static creation of the data-source correct? Would you change anything in the AbstractDao class that could pose a concurrency issue?
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);
}
}
My other question is if there are concurrency issues here, specifically in the servlet. Imagine 1000 requests simultaneously hitting the servlet. What worries me is the PersonDaoImpl.
1000 different threads and each gets it's own stack. So 1000 different instances of PersonDaoImpl. If we go to AbstractDao, it calls getConnection on the datasource.
So questions would be...
Does the getConnection() pose a concurrency issue?
Can the 1000 different requests pose a threat to the datasource object from the above code?
What if there was a private PersonDao personDao = new PersonDaoImpl() as an instance in the servlet. Now what happens?
What I'm really confused on is what is happening inside the doGet when the PersonDaoImpl is instantiated. Can someone give me a walkthrough please. The gist of my question is if the code I have up there is thread-safe.