Why methods annotated with #PostConstruct or #PreDestroy in singleton session beans with
container managed transactions can have only one of the following transaction attributes:
• REQUIRED
• REQUIRES_NEW
• NOT_SUPPORTED
I guess because #PostConstruct or #PreDestroy annotated methods are methods invoked by the container during bean creation or destruction, so making these methods part of mandatory transaction wouldn't make sense (since there are no business methods called before #PostConstruct). Same applies for SUPPORT type.
You can make the method transactional by itself (so this method becomes atomic) but it can't join other transactions because it is invoked by the container and you have no control over it.
Related
Using Spring, I am reaching the following scenario.
I have a service that has to be #Transactional because it calls several DAOs. But it also calls other services that are already #Transactional.
Somehow, I will be calling nested #Transactional services.
Will Spring manage well?
#Transactional without any explicit parameters uses propagation = REQUIRED. This means:
If there is no transaction in the current thread, a new transaction will be created
If there is a transaction, it will be used
The 2nd service (the nested one) annotated with #Transactional will be executed in the same transaction as the 1st one (the outer one). You don't need to do anything.
In some cases if you want to explicitly separate the nested call from the outer one you can use propagation = REQUIRES_NEW.
I have been studying ejb recently and I am also reading about the timer service as well, but even though I have read about Stateless, Stateful and Singleton types of Session Beans, I still have some trouble to figure out what makes the Timer Service have a multiple instance attribute.
I have seen some examples around, and even the simplest ones use the Singleton Session Bean, so, If I were to write a simple program to test it, would it be ok to use a Stateless Bean or is it recommended to use a Singleton anyway? Also, if possible, can I have a case where a Stateless would not be optimal?
Use a singleton if you want to ensure that all timeout callbacks are invoked on the same underlying bean instance. This is important if you want to maintain state in the bean instance itself, and you want to ensure that only one timeout callback can be invoked at a time (by default, the timeout callback will use the singleton's concurrency management settings, which by default is container-managed with a write lock, so only one method on the singleton can be invoked at a time).
Use a stateless if you want to allow multiple timeout callbacks to be invoked at once. The EJB container will create new bean instances if there are multiple timeout callbacks happening concurrently.
If you want to configure a non-persistent timer to begin running when the application begins running, then you can either use the #Schedule annotation on either a stateless or singleton bean, or you can use an #Singleton #Startup bean with an #PostConstruct (and if you want the stateless behavior, you can inject the stateless bean into the stateless bean and invoke a createTimer on the stateless session bean during startup).
The reasons it uses singletons are at least 2 fold:
1.
only singletons have the capabilities of start up initialization. That means, you are able to register your timer services when your application starts.
2.
if it were to use stateless beans, then a new timer service will be registered with every stateless bean setup to serve a request. A singleton guarantees that only one of a kind of your timer is registered. Imagine a contention or integrity issues, or money losses, were you to inadvertently use a timer in a stateless bean and then more than 1 is created at more or less the same time to serve requests.
I am learning about EJB's, so far I have read that multi-threading is not allowed in EJB'S, because it is the container who should care about thread-safety and let the developer only focus in the business logic, so basically that means that EJB ensures that only one thread has access at the same time to a method in a Session bean.
What happens then when we have many users accessing to the same method in a EJB?
Is the container serializing the acceses, or is creating different instances of the bean, one per thread?
Could someone explain me what is the policy about that? Also I am a bit confused, why if multithreading is not allowed, so we cannot create our own threads, why we have this #Asynchronous annotation?
Yes, it creates several instances, and pools them. See the official Oracle documentation:
Because a stateless session bean is never passivated, its lifecycle has only two stages: nonexistent and ready for the invocation of business methods. Figure 22-4 illustrates the stages of a stateless session bean.
The EJB container typically creates and maintains a pool of stateless session beans, beginning the stateless session bean’s lifecycle. The container performs any dependency injection and then invokes the method annotated #PostConstruct, if it exists. The bean is now ready to have its business methods invoked by a client.
At the end of the lifecycle, the EJB container calls the method annotated #PreDestroy, if it exists. The bean’s instance is then ready for garbage collection.
I am working on an EJB3 application with mainly stateless session beans (SLSB). They use container managed transactions (CMT).
I want the beans to be aware of the transactions (for logging, etc). I can implement the javax.ejb.SessionSynchronization to do this. I find that I can register a javax.transaction.Synchronization in a default interceptor also to get similar callbacks.
Are there any dis/advantages to using one over the other?
Multiple SLSB of the same type can be involved in the same transaction. As soon as a method exits, the SLSB is returned to a pool for use by the next invocation, so it is not safe for an SLSB instance to be "aware" of a transaction: by the time it is notified, the bean might be in use in another transaction.
As for SFSB, I would say there is no advantage between the two approaches in theory. However, the EJB container might be using Synchronization for various internal tasks, so using SessionSynchronization would allow the EJB container to have more control over the timing of the callbacks with respect to its own operations.
I just tried to use the javax.ejb.SessionSynchronization interface with a stateless session bean and was confused not to get any calls of the three implemented methods. Then I saw this comment in the javax.ejb.SessionSynchronization JavaDoc:
Only a stateful session bean with container-managed transaction demarcation can receive session synchronization notifications. Other bean types must not implement the SessionSynchronization interface or use the session synchronization annotations.
See also this thread for some more background. So my conclusion is that making stateless session beans transaction-aware using CMT can NOT be achieved with javax.ejb.SessionSynchronization.
in EJB 3.x for both the onMessage() method of MDBs and the #Timeout method of SLSBs and MDBs there is no transaction propagation. That is, there is no client for the execution of the method, so a transaction can't be possibly propagated.
When using Container-managed transactions, I would expect the two cases to accept the same javax.ejb.TransactionAttributeType. However, they don't.
For the onMessage() method, REQUIRED and NOT_SUPPORTED are the acceptable transaction attributes, whereas for #Timeout methods REQUIRED, REQUIRES_NEW and NOT_SUPPORTED.
In particular, for the #Timeout methods the spec says (par. 18.2.8):
Note that the container must start a
new transaction if the REQUIRED
(Required) transaction attribute is
used. This transaction attribute value
is allowed so that specification of a
transaction attribute for the timeout
callback method can be defaulted.
If I get this correctly, normally REQUIRES_NEW should be used here, but because REQUIRED is the default for an EJB, it is also allowed for #Timeout methods, giving it the same semantic as REQUIRES_NEW, since there is no possibility of a transaction to be propagated.
Questions:
Is my understanding correct?
Why isn't REQUIRES_NEW acceptable also in onMessage()? Is it different somehow in respect of transactions?
UPDATE:
The same goes for other cases where REQUIRES_NEW is supported: #Asynchronous and #PostConstruct/#PreDestroy methods.
Yes, your understanding is correct.
In my opinion, #Timeout is odd for specifying REQUIRES_NEW. The spec basically requires that the container update the persistent timer database within the same transaction as the timeout method. This isn't really any different than transactional JCA message delivery, except that it's more apparent in the JCA scenario that an external component is handling the transaction. I suppose you could argue that there is no JavaEE component driving the #Timeout method, but in my opinion, it would have been better to disallow REQUIRES_NEW for both. Regardless, the inconsistency is odd, so perhaps MDB will be updated in a later version of the spec to allow REQUIRES_NEW.