SessionContext RollBackOnly and MDB's - session

Having an MDB that receives a message in a transaction and then does several EJB calls if I call in one of those EJB's this.sessionContext.setRollbackOnly() will this trigger the JMS message's redelivery ?
All the EJB methods are marked with Requires_New transaction attribute.

No, because the MDB's transaction will be suspended while EJBs annotated with #REQUIRES_NEW are being processed — each within its own transaction. Additional assumption is that setRollbackOnly() is the only effect of rolling back an EJB's transaction, that is the EJB exited properly and did not throw any exception (after voting for rollback, further interaction with the resource may cause an exception from the javax.ejb.EJBException family to be thrown).

Related

Spring: Side effects of #Async on Transactions handling?

I have a Spring Boot REST API through which a web client can start the execution of a testsuite. The handling of the transactions was tricky, but i finally made it and everything work as expected. This is my setting:
the http request is handled by a controller (1)
when receiving the request, the controller publishes an event "start testsuite" (I use the Spring Event handling)
a method with #EventListener (2) listens to that event and calls the method in charge of the testsuite execution (3).
Now it turns out that the execution of the testsuite is sometime very long. As I don't want the http request to remain pending too long, I'd like to make the testsuite execution asynchron. To achieve that I added a #Async at the method of the service layer in charge of the testsuite execution(3).
As a result: I can tell that the process runs now indeed async but the testsuite execution behave in a weird way that make me think the transactions are not handled correctly anymore. So what I'm trying to understand, and that's the object of this question: in which way the #Async can, in this configuration, have side effects on the transaction handling?
I did some research. According to this article
If the #Async annotation is being used extra care should be taken with respect to transactions. In normal circumstances (without #Async) a transaction gets propagated through the call hierarchy from one Spring #Component to the other. However, when a #Transactional Spring #Component calls a method annotated with #Async this does not happen. The call to the asynchronous method is being scheduled and executed at a later time by a task executor and is thus handled as a 'fresh' call, i.e. without a transactional context. If the #Async method (or the #Component in which it is declared) is not #Transactional by itself Spring will not manage any needed transactions.
I get that point, but I don't think I'm in this situation since the calling method of the async method (= the event listener) has not been made transactional.
Does anyone have a clue?

Understanding Spring AOP and Transaction Aspect

I was studying about the Proxy Object which spring gives when we autowire any interface. This is a very good link for understanding that https://www.youtube.com/watch?v=bEvGdWjeCy4&t=310s. Here he explains that If a POJO implements any interface then Spring proxy bean also implements that interface (using JDK Proxy mechanism) and adds additional logic such as transactional logic (if the method was annotated using jdbc code or delegating it to PlatformTransactionManager). Spring gives us a wrapper object which has the reference to the real object and it has additional code which it runs before and after the original method is invoked using MethodInvocationHandler. So My question is that how exactly spring is managing that transaction.Where that jdbc code to get connection and start transaction is written. Is it in the Spring Proxy object or any Aspect Class.
As in AOP there as Aspects which are basically the cross cutting concerns such as transaction common to the whole application. Is Spring inserting Transaction behavior code in the Proxy Object or is it Using PlatformTransactionManager to do that And Where does This AOP fits in this Flow. How the Aspect handling Transactional behavior getting invoked here if it is. How the call is getting transferred to it?
In term of JDK proxy , you have to supply a InvocationHandler implementation when creating a proxy object. When the proxy object is invoked , this InvocationHandler will be invoked around the actual object. (see this for a hello world example for how does JDK proxy works)
In term of the spring transaction , it already shipped with an InvocationHandler implementation (i.e. JdkDynamicAopProxy). It will then somehow invoke the transaction aspect (i.e. TransactionInterceptor). The transaction aspect is responsible for controlling the whole workflow such as when to create , commit or rollback the transaction and when to actually execute the actual method etc.
The transaction aspect also delegates to the PlatformTransactionManager to actually start , commit and rollback a transaction. Because different technologies has their own ways to start , commit and rollback a transaction , it is necessary to introduce a PlatformTransactionManager as an interface to abstract these operations such that we can switch different transaction technology by simply switching the PlatformTransactionManager implementation inside the transaction aspect .
So back to your questions :
Where that jdbc code to get connection and start transaction is
written. Is it in the Spring Proxy object or any Aspect Class.
None of them. It is actually the PlatformTransactionManager to get the connection and start the transaction which is invoked by the aspect.
Is Spring inserting Transaction behaviour code in the Proxy Object or
is it Using PlatformTransactionManager to do that And Where does This
AOP fits in this Flow.
Spring inserts the transaction behaviour in the aspect object (i.e. TransactionInterceptor). The aspects then delegate to the PlatformTransactionManager to actually start , commit and rollback the transaction.
How the Aspect handling Transactional behaviour getting invoked here
if it is. How the call is getting transferred to it?
Assuming the JDK proxy is used , the call flow is something like :
Someone invokes on the JDK proxy
InvocationHandler of this proxy will be invoked (i.e JdkDynamicAopProxy)
InvocationHandler somehow calls spring transaction aspect (i.e TransactionInterceptor)
Transaction aspect delegates to PlatformTransactionManager to actually start , commit and rollback the transaction if necessary.

ServiceLocatorFactoryBean #transactional

can someone please explain it to me, is it possible to forward existing opened transaction to a service that has been created with ServiceLocatorFactoryBean in Spring, and how does the factory manages transactions.
I have issues with a transaction rollback in the service that was created by the factory, in a way that if I throw checked exception in it, the transaction will be committed regardless the fact that the exception occurred.
My service is annotated with #Transactional(propagation = Propagation.REQUIRED, rollbackFor = MyException.class), so it should use the existing transaction and it should rollback in case of the checked exception.
I assume that somehow, a new transaction is opened during creation of a new service, so although one transaction gets rollbacked, the other one gets committed independently.

Rolling back a transaction in Spring ApplicationListener

Normal Spring ApplicationListners are running synchronously within the same thread of the event publisher.
Is there any way to rollback the main context transaction in the listener?
I have a method annotated #Transactional and it publishes an event, I want to make execute the listeners in the scope of the main method, and rollback the main transaction in case of exceptions.
I am using a LocalTransactionManager on Hibernate SessionFactory.
Is there any way to do this using Spring 3.3.x?

Catch spring transaction exception in service

i'd like to catch spring transaction exception in service layer not in the service heighr layer or the service caller.
As i found i can not catch the exception in the #transaction method.i need to take an action once the the transaction failes in the same method or the same service.
Transaction is rolled back when exception is thrown from method annotated with #Transactional (or class can be annotated with #Transactional).
So you can't do post rollback actions in this method. If you want to do this logic on service layer, you can have service bean handling post rollback action call another service bean which handles transaction.

Resources