Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Correct Design and Concurrency Issues  RSS feed

 
Greg Bag
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello guys, 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?











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.




 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First, I would make the createPerson method return something that tells me if the create was successful or not and I wouldn't just hide the exception with that catch block.
You should be fine with regards to concurrency because you are not keeping state in your servlets and you are not keeping a connection as an instance variable. Generally when it comes to connections you should get one when you need it (in the method that needs it) and close it soon after using it.

 
Greg Bag
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
E Armitage wrote:First, I would make the createPerson method return something that tells me if the create was successful or not and I wouldn't just hide the exception with that catch block.
You should be fine with regards to concurrency because you are not keeping state in your servlets and you are not keeping a connection as an instance variable. Generally when it comes to connections you should get one when you need it (in the method that needs it) and close it soon after using it.



Great! So what would you do with that exception? Can you give me an example code snippet. I usually have a logger log the exception. But above all, the design is correct yes?
 
Marshall Blythe
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greg Bag wrote:
Does the getConnection() pose a concurrency issue?
Can the 1000 different requests pose a threat to the datasource object from the above code?


The DataSource is just an interface, but most implementations that you obtain via JNDI lookup in a JEE container are thread-safe. In addition, most of them support connection pooling. Consult the documentation for your JDBC driver to be sure.

Greg Bag wrote:
What if there was a private PersonDao personDao = new PersonDaoImpl() as an instance in the servlet. Now what happens?


As long as the PersonDaoImpl is thread-safe then there's no harm in keeping a reference to it in an instance variable.

Greg Bag wrote:
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.


Since the DataSource is looked up once during static initialization of the AbstractDao the instantiation of PersonDaoImpl is very light weight. So long as your DataSource is thread-safe (and most are) then the rest of the code you posted is thread-safe.
 
Greg Bag
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So is this personDaoImpl thread-safe? If I was to use a single instance variable in the servlet, that wouldn't pose an issue? What if 1000 requests call createPerson at the same time on the same instance of PersonDaoImpl?
 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greg Bag wrote:So is this personDaoImpl thread-safe? If I was to use a single instance variable in the servlet, that wouldn't pose an issue? What if 1000 requests call createPerson at the same time on the same instance of PersonDaoImpl?

There are no instance variables being updated so you can use one instance of the class for the whole application without problems. You just need to handle the possible exceptions and return values. You also need to think about the application consistency. Can you have many records with the same firstname and lastname? If not then typically you add constraints that prevent this on the database and make your code anticipate an exception due to that constraint.
 
Marshall Blythe
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greg Bag wrote:So is this personDaoImpl thread-safe? If I was to use a single instance variable in the servlet, that wouldn't pose an issue? What if 1000 requests call createPerson at the same time on the same instance of PersonDaoImpl?


It's thread-safe, but you need to consider using the connection pooling features of your DataSource if your servlet is going to be handling hundreds of concurrent requests. The connection pool is usually administered in the JEE container and is transparent to the client application. Check your JDBC driver and JEE container documentation to see how to setup a connection pool.
 
Greg Bag
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I still don't understand the thread-safety portion. Let's say there is 1 instance in the servlet for PersonDaoImpl(). 5 different requests come in at the same exact time and call createPerson(firstname, lastname) on the PersonDaoImpl(), can't that corrupt data? Before the firstname/lastname is done updating by the 1st request, the 2nd request changes the firstname/lastname variables.
 
Greg Bag
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Marshall Blythe wrote:
Greg Bag wrote:So is this personDaoImpl thread-safe? If I was to use a single instance variable in the servlet, that wouldn't pose an issue? What if 1000 requests call createPerson at the same time on the same instance of PersonDaoImpl?


It's thread-safe, but you need to consider using the connection pooling features of your DataSource if your servlet is going to be handling hundreds of concurrent requests. The connection pool is usually administered in the JEE container and is transparent to the client application. Check your JDBC driver and JEE container documentation to see how to setup a connection pool.


The code above shows connection pooling.
 
E Armitage
Rancher
Posts: 989
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greg Bag wrote:I still don't understand the thread-safety portion. Let's say there is 1 instance in the servlet for PersonDaoImpl(). 5 different requests come in at the same exact time and call createPerson(firstname, lastname) on the PersonDaoImpl(), can't that corrupt data? Before the firstname/lastname is done updating by the 1st request, the 2nd request changes the firstname/lastname variables.

Each request will be processed with the firstname and lastname details that it got when the request started. Values from the second request won't change values for the first request. That would have been the case if you had the firstname and lastname as instance variables.
 
Marshall Blythe
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greg Bag wrote:The code above shows connection pooling.


Yes, you're handling the connection properly, but you may need to fine-tune the connection pool to ensure that it performs well under load (e.g. check the max # of pooled connections, connection eviction policy etc.). That can come later during the load/stress testing phase of your project.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!