In below code , when methodInner() is called from within methodOuter, should be under transaction bounds. But it is not. But when methodInner() is called directly from MyController class , it is bound by transaction. Any explanations?
This is controller class.
@Controller
public class MyController {
@Autowired
@Qualifier("abcService")
private MyService serviceObj;
public void anymethod() {
// below call cause exception from methodInner as no transaction exists
serviceObj.methodOuter();
}
}
This is service class.
@Service("abcService")
public class MyService {
public void methodOuter() {
methodInner();
}
@Transactional
public void methodInner() {
.....
//does db operation.
.....
}
}
It is not sufficient to tell you simply to annotate your classes with the @Transactional annotation, add the line ( <tx:annotation-driven/> ) to your configuration, and then expect you to understand how it all works.
If you call a method with a @Transactional annotation from a method with @Transactional within the same instance, then the called methods transactional behavior will not have any impact on the transaction.
Annotation Type Transactional. Describes a transaction attribute on an individual method or on a class. When this annotation is declared at the class level, it applies as a default to all methods of the declaring class and its subclasses.
The @Transactional annotation belongs to the Service layer because it is the Service layer's responsibility to define the transaction boundaries.
Spring uses Java proxies by default to wrap beans and implement annotated behavior. When doing calls within a service you bypass proxy and run method directly, so annotated behavior is not triggered.
Possible solutions:
Move all @Transactional
code to separate service and always do calls to transactional methods from outside
Use AspectJ and weaving to trigger annotated behavior even within a service
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With