5

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.
    .....
    }
}
santhosh
  • 484
  • 3
  • 10
cyrilantony
  • 274
  • 3
  • 14
  • Have you added @EnableTransactionManagement to your configuration? – Ludwig Magnusson Sep 26 '14 at 11:08
  • 2
    Works as expected as that is the way how proxies work, only external method calls (i.e calls INTO the object) are intercepted, calls from within the object aren't intercepted. – M. Deinum Sep 26 '14 at 11:11
  • 1
    http://stackoverflow.com/a/24902434/2504224 Replace `@Async` with `@Transactional` and effectively you have your answer – geoand Sep 26 '14 at 11:11
  • @Ludwig Magnusson : No,i have not used EnableTransactionManagement .But i have put in xml config files. I hope that is enough. Spring is able to execute other methods under transaction bounds. Only for this special case it is not working. – cyrilantony Sep 26 '14 at 11:16

2 Answers2

6

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:

  1. Move all @Transactional code to separate service and always do calls to transactional methods from outside

  2. Use AspectJ and weaving to trigger annotated behavior even within a service

hoaz
  • 9,883
  • 4
  • 42
  • 53
0

Add @Transactional to methodOuter() and it works.