Cheat Sheet: New Features in JPA 2.1

JPA 2.1 introduced 12 new features, like StoreProcedureQueries, Entity Graphs and Attribute Converter, to make your work with the database easier and more efficient.
Download your free New Features in JPA 2.1 cheat sheet now, to get all the information you need to improve your database access.

This 5 page cheat sheet brings you:

- a short description and
- code snippets for each feature,
- links to more detailed articles.

Signup now and get your free New Features in JPA 2.1 cheat sheet and regular blog updates.

I respect your privacy and have ZERO TOLERANCE for spam!

Java EE Pitfalls #1: Ignore the default lock of a @Singleton

EJB Singleton Beans were introduced by the EJB 3.1 specification and are often used to store cached data. This means, we try to improve the performance of our application by using a Singleton. In general, this works quite well. Especially if there are not too many calls in parallel. But it changes if we ignore the default lock and the number of parallel calls increases.


Sensible defaults

Let's start with some Java code and see how the sensible default of the lock works out. The following snippet shows a simple EJB Singleton with a counter and two methods. method1 writes the current value of the counter to the log and method2 counts from 0 to 100.


As you can see, there is no lock defined. What do you expect to see in the log file, if we call both methods in parallel?


OK, that might be a little unexpected, the default is a container managed write lock on the entire Singleton. This is a good default to avoid concurrent modifications of the attributes. But it is a bad default if we want to perform read-only operations. In this case, the serializationion of the method calls will result in a lower scalability and in a lower performance under high load.

How to avoid it?

The answer to that question is obvious, we need to take care of the concurrency management. As usual in Java EE, there are two ways to handle it. We can do it ourself or we can ask the container to do it.

Bean Managed Concurrency

I do not want to go into too much detail regarding Bean Managed Concurrency. It is the most flexible way to manage concurrent access. The container allows the concurrent access to all methods of the Singleton and you have to guard its state as necessary. This can be done by using synchronized and volatile. But be careful, quite often this is not as easy as it seems.

Container Managed Concurrency

The Container Managed Concurrency is much easier to use but not as flexible as the bean managed approach. But in my experience, it is good enough for common use cases.

As we saw in the log, container managed concurrency is the default for an EJB Singleton. The container sets a write lock for the entire Singleton and serializes all method calls.
We can change this behavior and define read and write locks on method and/or class level. This can be done by annotating the Singleton class or the methods with @javax.ejb.Lock(javax.ejb.LockType). The LockType enum provides the values WRITE and READ to define an exclusive write lock or a read lock.

The following snippet shows how to set the Lock of method1 and method2 to LockType.READ.

As already mentioned, we could achieve the same by annotating the class with @Lock(LockType.READ) instead of annotating both methods.

OK, if everything works as expect it, both methods should be accessed in paralel. So lets have a look at the log file.

Conclusion


At the beginning of this article, we found out that Java EE uses a container managed write lock as default. This results in a serialized processing of all method calls and lowers the scalability and performance of the application. This is something we need to have in mind when implementing an EJB Singleton.

We had a look at the two exisiting options to control the concurrency management: the Bean Managed Concurrency and the Container Managed Concurrency.
We used the container managed approach to define a read lock for both methods of our singleton. This is not as flexible as the bean managed approach, but it is much easier to use and sufficient in most of the cases. We just need to provide an annotation and the container will handle the rest.

If you enjoyed reading this article and like to learn more about other Java EE features and pitfalls, make sure to subscribe to this blog and follow me on twitter and google+.

Do you know of other Java or Java EE related pitfalls that I should cover in blog post? Please write me a comment and I will cover it in one my next episode of Java EE Pitfalls!

4 comments:

  1. You should widen the content part of your page. It's harder to read your example code when some lines are split in two. Firefox 30.

    ReplyDelete
  2. Actually it's not line splitting that's the problem, it's the indenting in your code. For example in the first code block the line "this.logger.info("method1: " + counter);" is indented by just one space character when it should be more like 8, considering you're using 4 space indentation everywhere else.

    ReplyDelete
  3. Thanks for posting this link.
    Using Bean Managed Concurrency is an option, of course. But I personally prefer the Container Managed Concurrency. It is easier and sufficient in nearly all of the cases.

    ReplyDelete