problem
Under normal circumstances, we are all called in the controller in service in the method, which if need to add a transaction, you add @Transactional on the method, this is no problem, the transaction will take effect.
But if something like this around the following, service method calls the method in their own classes, this time even added @Transactional, the transaction will not take effect.
@Controller public class TestController { @Autowired private TestService testService; @GetMapping("/test") public void test(){ testService.methodB(); } }
@Service public class the TestService { @Transactional public void methodA () { } / ** * called here methodA () will fail transaction * / public void methodB () { the this .methodA (); } }
the reason
Because, spring transaction is realized using a proxy class to implement, but this.methodA here (), and did not take TestService proxy class, so the transaction will fail.
solve
Method 1: The methodA () and methodB () are placed in a different class.
Method 2: themselves into their own, calling injected with examples
@Service public class TestService { @Autowired Private TestService TestService; the @Transactional public void methodA () { } / ** * called here methodA () transaction will take effect * / public void methodB () { testService.methodA (); } }
Method 3: Obtain the proxy class, call the method using the proxy class of their own class
@Service public class TestService { the @Transactional public void methodA () { } / ** * called here methodA () transaction will take effect * / public void methodB () { ((TestService) the AopContext.currentProxy ()). MethodA ( ); } }
At last
The spring aop agents have jdk cglib agents and agent implementation, with specific reference to the java proxy, proxy static and dynamic spring aop agents and agents, to achieve the principle of unified summary
// if the proxy object AopUtils.isAopProxy (the AopContext.currentProxy ()); // whether cglib proxy object AopUtils.isCglibProxy (the AopContext.currentProxy ()); // if jdk dynamic proxy AopUtils.isJdkDynamicProxy (AopContext.currentProxy ());