Managing Concurrent Access in a Singleton Bean Session

I talked with an employee about concurrency management in singleton session beans. As far as I understand, after reading the Oracle documentation , if you did not @ConcurrencyManagement annotation, then the container-controlled concurrency is used by default. The documentation in it says the following about a Singleton session managed by a beans container:

The javax.ejb.Lock annotations and the javax.ejb.LockType type are used to indicate the access level of singleton business methods or @Timeout methods.

and

If the singleton class does not have @Lock annotation, the default lock type @Lock (LockType.WRITE) applies to all business methods and timeouts.

Now, if you annotate a bean using @ConcurrencyManagement(ConcurrencyManagementType.BEAN) , you are responsible for ensuring that the bean state is synchronized for all clients using the synchronized and other standard Java concurrency functions. The article even says:

Developers who create singlets with a bean-controlled concurrency allow the use of Java programming language synchronization primitives, such as synchronization and volatile, to prevent concurrent access errors.

I have not seen this anywhere in the container-driven concurrency section, which led me to believe that if you want to synchronize things yourself, you need to annotate the class using @ConcurrencyManagement(ConcurrencyManagementType.BEAN) .

My colleague made a comment saying that β€œthe person you guys are doing strange things” when he saw this annotation on my bean who started this discussion.

None of its beans has the @ConcurrencyManagement annotation, but it uses the synchronized throughout the class. Am I right in saying that any finer synchronization that he uses is pointless because all of his business methods have an implicit @Lock(LockType.WRITE) annotation @Lock(LockType.WRITE) ? This means that if the client calls one of its methods, then no other client can call any bean method, so explicit synchronization inside the method will be useless.

For example, for some lock myLock used in synchronized (myLock) as part of one of its business methods, there will be no competition for this lock because the methods are effectively synchronized.

Correct me if I am wrong, but it looks like his methods basically look like this:

 public synchronized void myMethod() { // do stuff synchronized (lock) { // modify mutable state } } public synchronized void myOtherMethod() { // do other stuff synchronized (lock) { // modify mutable state } } 

Assuming that the lock is created in this singleton bean session only to protect the volatile state in the bean, it seems that it serves no purpose when using container-controlled concurrency.

Thanks in advance for any understanding of this!

+5
source share
2 answers

As a rule, you are right with all your expectations. There is one minor case where your peer code may use synchronization primitives.

If the ejb-jar.xml file exists, it can set up concurrency control under bean control. It will look something like this:

 <enterprise-beans> <session> <ejb-name>MySingletonEJB</ejb-name> <ejb-class>com.blah.MySingletonEJB</ejb-class> <transaction-type>Bean</transaction-type> ... </session> ... </enterprise-beans> 

Since EJB 3, this is a really bad way of doing things, and annotations are definitely preferred because the configuration is correct with the source code.

0
source

You are right, but it depends on what it is blocked for, if the object is tied to this single tone, then he really knows everyone who actually slows down the program due to a double lock.

0
source

All Articles