Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managing Concurrent Access in a Singleton Session Bean

I got into a discussion with a co-worker about concurrency management in singleton session beans. From my understanding, after reading the Oracle documentation, if you leave off the @ConcurrencyManagement annotation, then it defaults to container-managed concurrency. In the documentation it states the following about container-managed singleton session beans:

The javax.ejb.Lock annotation and a javax.ejb.LockType type are used to specify the access level of the singleton's business methods or @Timeout methods.

and

If no @Lock annotation is present on the singleton class, the default lock type, @Lock(LockType.WRITE), is applied to all business and timeout methods.

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

Developers who create singletons with bean-managed concurrency are allowed to use the Java programming language synchronization primitives, such as synchronization and volatile, to prevent errors during concurrent access.

I didn't see this anywhere in the section on container-managed concurrency, leading me to believe that if you want to synchronize things yourself, you need to annotate the class with @ConcurrencyManagement(ConcurrencyManagementType.BEAN).

My co-worker made a comment saying that "man you guys do some strange stuff" when he saw this annotation on my bean, which started this discussion.

None of his beans have any @ConcurrencyManagement annotation, but he uses the synchronized keyword throughout the class. Am I correct in saying that any finer-grained synchronization he is using is pointless, because all of his business methods have an implicit @Lock(LockType.WRITE) annotation? This would mean that if a client calls one of his methods, then no other client can call any method of the bean, so explicit synchronization within the method would be useless.

For example, for some lock myLock used in synchronized (myLock) within one of his business methods, there would be no contention for that lock since the methods are effectively synchronized themselves.

Correct me if I'm wrong, but it seems 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 lock is created in this singleton session bean just to protect mutable state within the bean, it seems that it doesn't serve any purpose when using container-managed concurrency.

Thanks in advance for any insight into this!

like image 449
Evan LaHurd Avatar asked May 13 '16 20:05

Evan LaHurd


People also ask

What does @startup mean on a @singleton Bean?

@Startup Marks a singleton bean for eager initialization during the application startup sequence. @DependsOn Used to express an initialization dependency between singleton components.

Are singletons stateless?

Singleton Session Beans are similar to Stateless Session Beans but only one instance of the Singleton Session Bean is created in the whole application and does not terminates until the application is shut down. The single instance of the bean is shared between multiple clients and can be concurrently accessed.

What is @singleton annotation in Java?

What is singleton? Singleton Pattern in android. A single instance of a class providing a global point of access to itself during the entire application's lifetime. @Singleton annotation in Dagger. A single instance of a class which is unique to a specific component, its access is limited to the scope of the component.


1 Answers

Generally, you are correct with all of your expectations. There is one minor case where your coworker's code could actually make use of the synchronization primitives.

If an ejb-jar.xml file exists, it can set the concurrency management to be managed by the bean. It would 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 really a bad way to do things and annotations are definitely preferred because the configuration is right with the source.

like image 182
Chill Avatar answered Oct 02 '22 02:10

Chill