EJB 3.1 introduced timeout related annotations as a part of its API.
- @AccessTimeout
- @StatefulTimeout
Let’s quickly look at what they are and why are they important
@AccessTimeout
Specifies the time period after which a queued request (waiting for another thread to complete) times out.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Singleton | |
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) //this is actually by default | |
public class Singleton_With_Timeout{ | |
@AccessTimeout(value = 5000, unit = java.util.concurrent.TimeUnit.MILLISECONDS) | |
@Lock(LockType.WRITE) //default configuration | |
public void find(){ | |
//… business logic | |
} | |
} |
When your session bean instances are bombarded with concurrent requests, the EJB container ensures sanity by serializing these calls i.e. blocking other threads until the current thread finishes execution. You can refine this behavior further by using this annotation.
Which beans can leverage this annotation ?
This is applicable for
- Stateful (@Stateful) beans and
- Singleton beans (@Singleton) configured with container managed concurrency option (ConcurrencyManagementType.CONTAINER)
Why is it important ?
Since the EJB container serializes concurrent requests, having this annotation ensures that the potential (waiting) threads are not kept blocked for ever and helps define a concurrency policy.
Where can I put this annotation?
- On a class – globally applies to a all the methods
- On a particular method only
- On a particular method to override the settings of the class level annotation
How to use it ?
You can use the value and unit elements of this annotation to define its behavior
Here are a few options
- @AccessTimeout(0) – this means that your method does not support concurrent access at all and the client would end up getting a java.ejb.ConcurrentAccessException
- @AccessTimeout(-1) – your method will block indefinitely (I don’t think that’s good idea !)
- @AccessTimeout(5000) – method will wait for 5000 ms (5 seconds) before the next thread in queue (if any) if given a chance
Few things to note
- Default value for the unit element is java.util.concurrent.TimeUnit.MILLISECONDS
- a timeout value of less than -1 is invalid
@StatefulTimeout
Defines the threshold limit for eviction of idle stateful session beans i.e. the ones which have not received client requests for a specific interval
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@StatefulTimeout(15000,java.util.concurrent.TimeUnit.MILLISECONDS) | |
public class SFSB_With_Timeout{ | |
public void register(){ | |
//….business logic | |
} | |
} |
Why is it important ?
Imagine you have a stateful session bean handling a user registration workflow. The user is inactive for certain time interval (probably doing other stuff). How long would you want your stateful session bean active in the memory ? Configuring this annotation can help prevent inactive bean instances from hogging the main memory.
Where can I put this annotation?
Same rules as the @AccessTimeout annotation !
How to use it ?
You can use the value and unit elements of this annotation to define its behavior
Here are a few options
- @StatefulTimeout(0) – this means that your bean instance will be removed immediately after the completion of the method which holds this annotation
- @StatefulTimeout(-1) – your method will not be sensitive to time outs (man that’s stubborn !)
- @StatefulTimeout(15000) – method will wait for 15000 ms (15 seconds) for client requests before it becomes a candidate for eviction
Few things to note
- Default value for the unit element is java.util.concurrent.TimeUnit.MILLISECONDS
- a timeout value of less than -1 is invalid
Cheers !
@AccessTimeout(-1) – your method will block indefinitely (I don’t think that’s good idea !)
Why do you think that’s a bad idea? Our recent app tests revealed that most of the instability originates from the timeout. We cannot set it to 30s or 60s because there will always be something that lasts 61s.
LikeLike
As usual – ‘it depends’ 🙂 having indefinite timeout will lead to hogging of resources since requests would get queued up
LikeLike
In our env some processes that usually last 0,5 second may last even 20 seconds when the app has just been deployed and is initializing.
And how do you use the @AccessTimeout annotation in real life apps?
LikeLike
The answer would vary for different type of beans for which this annotation is applicable for. Which ones are you using? Singleton or Stateful ?
LikeLike
Pingback: Implementing auto retry in Java EE applications | Thinking in Java (at least trying to!)
Here is an option (or a work around) – https://abhirockzz.wordpress.com/2015/11/04/implementing-auto-retry-in-java-ee-applications/
LikeLike
Pingback: Implementing Auto Retry in Java EE Applications -