Spring事務調用類自己方法失效解決辦法和原因


問題

正常情況下,我們都是在controller里調用service里的方法,這個方法如果需要加事務,就在方法上加上@Transactional,這樣是沒問題的,事務會生效。

可是如果像下面這樣,繞以下,service里方法調用了自己類的方法,這個時候即使加了@Transactional,事務也不會生效。

@Controller
public class TestController {
    
    @Autowired
    private TestService testService;
    
    @GetMapping("/test")
    public void test(){
        testService.methodB();
    }
    
}
@Service
public class TestService {

    @Transactional
    public void methodA(){

    }

    /**
     * 這里調用methodA() 的事務將會失效
     */
    public void methodB(){
        this.methodA();
    }

}

原因

因為,spring的事務實現是使用了代理類來實現,而這里的this.methodA(),並沒有走TestService的代理類,所以事務會失效。

解決

方法1:把methodA()和methodB()分別放到不同的類里。

方法2:自己注入自己,用注入的實例調用

@Service
public class TestService {

    @Autowired
    private TestService testService;
    
    @Transactional
    public void methodA(){

    }

    /**
     * 這里調用methodA() 的事務將會生效
     */
    public void methodB(){
        testService.methodA();
    }

}

方法3:獲取代理類,利用代理類調用自己類的方法

@Service
public class TestService {

    @Transactional
    public void methodA(){

    }

    /**
     * 這里調用methodA() 的事務將會生效
     */
    public void methodB(){
        ((TestService)AopContext.currentProxy()).methodA();
    }

}

最后

spring的aop代理有jdk代理和cglib代理實現,具體參閱java中代理,靜態代理,動態代理以及spring aop代理方式,實現原理統一匯總

        //是否代理對象
        AopUtils.isAopProxy(AopContext.currentProxy());

        //是否cglib 代理對象
        AopUtils.isCglibProxy(AopContext.currentProxy());

        //是否jdk動態代理
        AopUtils.isJdkDynamicProxy(AopContext.currentProxy());

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM