Evan LaHurd
Evan LaHurd

Reputation: 977

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!

Upvotes: 10

Views: 3912

Answers (2)

highstakes
highstakes

Reputation: 1519

You are correct, but it depends on what he is locking on, if the object is tied to that singleton only then he is indeed a know-it-all who is actually slowing down the execution of the program because of the double locking.

Upvotes: 0

Chill
Chill

Reputation: 1113

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.

Upvotes: 2

Related Questions