原本以為自己看了這麼久的原始碼,分享效果應該不錯,但是發現不是這樣的,大部分人都是處於以為自己知道,實際上自己似是而非的情況。雖然細節,大的主線自己比較清楚,但是在告訴大家的時候,不是所有人的理解程度都和自己一樣。
可能自己在講的時候,大家以為自己理解了,但是推敲推敲,就能提出很多的疑問,如果將的範圍比較大,就容易把自己也繞暈了。
事務不生效的幾個結論
- private,protect方法事務不生效
- final修飾符修飾的方法和類不生效。
- 在當前的bean中,沒有加上事務的方法呼叫有事務的方法不生效。如下,呼叫index方法,save方法上的事務不生效。
public String index(@RequestParam("name") String name,
@RequestParam("age") Integer age,
@RequestParam("id") Integer id
){
save(name,age,id);
return "index";
}
@RequestMapping("/tx")
@ResponseBody
@Transactional
public String save(@RequestParam("name") String name,
@RequestParam("age") Integer age,
@RequestParam("id") Integer id){
System.out.println("hello");
jdbcTemplate.update("insert into user(id,name,age)values(" + id + ",'"+name+"',"+age+")");
jdbcTemplate.update("insert into user(id,name,age)values(2,'"+name+"',"+age+")");
return "tx";
}
複製程式碼
疑問
-
CGLib動態代理時,為什麼private方法和protect方法是不生效的呢?
大家為了方便記憶,都會說CGLib的動態代理是基於繼承的實現,而子類無法訪問private方法,所以不生效。實際這是錯誤的
真實情況,CGLib可以修改位元組碼,在子類中實現動態代理是完全可以的,之所以沒有生效則是因為Spring的事務註解在被Spring解析的時候,Spring會判斷事務的方法是不是public修飾符,如果不是public修飾符的話,則不使用事務代理。
AbstractFallbackTransactionAttributeSource類中
-
為什麼final方法是不生效的呢?
同樣的原因,在Spring建立動態代理的時候,會判斷方法的修飾符是不是final的方法,如果是Final方法則直接走原始的方法,而不經過代理方法。
另外不經過Spring的CGLib也不會代理final的方法
CGLibAopProxy的ProxyFilter類。 假設讀者對Enhancer很熟悉了
-
另外還有問題
Spring生成的動態代理與代理的物件是兩個Bean嗎?一個Bean包裝了原本的bean
注入的時候注入的是代理Bean還是實際的Bean?代理Bean
Aop的增強(Advice)和Proxy是什麼關係?分JDK和CGLib,一般代理與增強是合成的...
多個AOP切到同一個切點的時候如何處理?獲取攔截鏈,一個個執行
總結
分享的時候有疑問肯定是正常的,分享與做需求一樣,要明白聽眾的需求是什麼,能不能解決聽眾的需求。在自己看的時候,主線是正常的,分享的時候有疑問丟擲來,才能檢查自己是不是真的懂了這個知識點。
我講的時候有幾個講的不好的地方:
- 講的東西太多,原本只是講Spring不生效原理,結果之外又說了Spring Bean生命週期,其它的東西去了,講的點多,就沒辦法把一個點將的讓大家很明白。
- 在看的時候,自己給自己提的問題少,一旦大家一起提疑問的時候,能發現有的自己搞的不是很明白。
不過也好,對Spring事物處理這塊有更多的理解了。