spring的兩種常用事務傳播屬性說明
七種傳播屬性:
1.REQUIRED 如果存在當前事務則用當前事務,如果不存在當前事務,則新建一個事務
2.REQUIRES_NEW 如果當前存在事務則掛起當前事務,開啟一個新事務,新事務執行完畢後,喚醒之前掛起的事務,繼續執行。如果不存在當前事務,則新建一個事務
第一種情況:
執行controller以後事務會回滾,兩條數都插不進去。(propagation如果不寫預設的是Propagation.REQUIRED,都是同一個事務,在第二個service丟擲異常時,這個事務就會回滾)
第二種情況:
執行controller以後事務會回滾,Tuser會插入到資料表中,TOrder不會插入到資料表中。(在第一個service的事務傳播屬性是requires_new,在執行us.addUser()時,會把當前事務掛起,新建立一個事務,在user插入完成之後,事務提交,user資料入庫,然後再釋放掛起的事務,然後再執行os.addOrder(),丟擲異常,事務回滾,order資料不會入庫)
第三種情況
執行controller以後事務會回滾,兩條數都插不進去。(在執行us.addUser()時,當前已經有事務了,addUser方法就會使用當前事務,進行執行,執行完成之後,事務不會提交,因為事務的作用方法還沒有執行完成,然後會繼續執行addOrder方法,addOrder方法會掛起當前事務,建立一個新事務,執行時出現異常,新建的事務就會回滾,order資料不會入庫,然後釋放之前掛起的事務,這個被釋放的事務變成當前事務,由於addOrder方法裡面沒有捕捉異常,所以controller裡面也會丟擲異常,此時事務就會回滾,user資料也不會入庫)
第四種情況
執行controller以後,Tuser會插入到資料表中,TOrder不會插入到資料表中。(在第一個service,addUser()方法執行完成後事務會正常提交,然後事務狀態變成已完成
注意:spring事務是基於aop實現的。(只有來自外部方法的呼叫才會被aop代理捕獲,類的內部方法呼叫不會被aop代理,即使此方法上面加了@Transactional註解)