當前位置:編程學習大全網 - 源碼下載 - spring 4.0 resources不生效

spring 4.0 resources不生效

壹 事務不生效1.訪問權限問題眾所周知,java的訪問權限主要有四種:private、default、protected、public,它們的權限從左到右,依次變大。但如果我們在開發過程中,把有某些事務方法,定義了錯誤的訪問權限,就會導致事務功能出問題,

}我們可以看到add方法的訪問權限被定義成了private,這樣會導致事務失效,spring要求被代理方法必須是public的。說白了,在AbstractFallbackTransactionAttributeSource類的computeTransactionAttribute方法中有個判斷,如果目標方法不是public,則TransactionAttribute返回null,即不支持事務。也就是說,如果我們自定義的事務方法(即目標方法),它的訪問權限不是public,而是private、default或protected的話,spring則不會提供事務功能。

2. 方法用final修飾有時候,某個方法不想被子類重新,這時可以將該方法定義成final的。普通方法這樣定義是沒問題的,但如果將事務方法定義成final,

}我們可以看到add方法被定義成了final的,這樣會導致事務失效。為什麽?如果妳看過spring事務的源碼,可能會知道spring事務底層使用了aop,也就是通過jdk動態代理或者cglib,幫我們生成了代理類,在代理類中實現的事務功能。但如果某個方法用final修飾了,那麽在它的代理類中,就無法重寫該方法,而添加事務功能。註意:如果某個方法是static的,同樣無法通過動態代理,變成事務方法。

3.方法內部調用有時候我們需要在某個Service類的某個方法中,調用另外壹個事務方法,

}我們看到在事務方法add中,直接調用事務方法updateStatus。從前面介紹的內容可以知道,updateStatus方法擁有事務的能力是因為spring aop生成代理了對象,但是這種方法直接調用了this對象的方法,所以updateStatus方法不會生成事務。由此可見,在同壹個類中的方法直接內部調用,會導致事務失效。那麽問題來了,如果有些場景,確實想在同壹個類的某個方法中,調用它自己的另外壹個方法,該怎麽辦呢?3.1 新加壹個Service方法這個方法非常簡單,只需要新加壹個Service方法,把@Transactional註解加到新Service方法上,把需要事務執行的代碼移到新方法中。具體代碼如下:@Servcie

public class ServiceA

}可能有些人可能會有這樣的疑問:這種做法會不會出現循環依賴問題?答案:不會。其實spring ioc內部的三級緩存保證了它,不會出現循環依賴問題。但有些坑,如果妳想進壹步了解循環依賴問題,可以看看我之前文章《spring:我是如何解決循環依賴的?》。3.3 通過AopContent類在該Service類中使用AopContext.currentProxy()獲取代理對象上面的方法2確實可以解決問題,但是代碼看起來並不直觀,還可以通過在該Service類中使用AOPProxy獲取代理對象,實現相同的功能。

}4.未被spring管理在我們平時開發過程中,有個細節很容易被忽略。即使用spring事務的前提是:對象要被spring管理,需要創建bean實例。通常情況下,我們通過@Controller、@Service、@Component、@Repository等註解,可以自動實現bean實例化和依賴註入的功能。當然創建bean實例的方法還有很多,有興趣的小夥伴可以看看我之前寫的另壹篇文章《@Autowired的這些騷操作,妳都知道嗎?》如果有壹天,妳匆匆忙忙的開發了壹個Service類,但忘了加@Service註解,比}從上面的例子中,我們可以看到事務方法add中,調用了事務方法doOtherThing,但是事務方法doOtherThing是在另外壹個線程中調用的。這樣會導致兩個方法不在同壹個線程中,獲取到的數據庫連接不壹樣,從而是兩個不同的事務。如果想doOtherThing方法中拋了異常,add方法也回滾是不可能的。如果看過spring事務源碼的朋友,可能會知道spring的事務是通過數據庫連接來實現的。當前線程中保存了壹個map,key是數據源,value是數據庫連接。private static final ThreadLocal> resources =

new NamedThreadLocal("Transactional resources");我們說的同壹個事務,其實是指同壹個數據庫連接,只有擁有同壹個數據庫連接才能同時提交和回滾。如果在不同的線程,拿到的數據庫連接肯定是不壹樣的,所以是不同的事務。6.表不支持事務周所周知,在mysql5之前,默認的數據庫引擎是myisam。它的好處就不用多說了:索引文件和數據文件是分開存儲的,對於查多寫少的單表操作,性能比innodb更好。有些老項目中,可能還在用它。在創建表的時候,只需要把ENGINE參數設置成MyISAM即可:CREATE TABLE `category` ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_binmyisam好用,但有個很致命的問題是:不支持事務。如果只是單表操作還好,不會出現太大的問題。但如果需要跨多張表操作,由於其不支持事務,數據極有可能會出現不完整的情況。此外,myisam還不支持行鎖和外鍵。所以在實際業務場景中,myisam使用的並不多。在mysql5以後,myisam已經逐漸退出了歷史的舞臺,取而代之的是innodb。有時候我們在開發的過程中,發現某張表的事務壹直都沒有生效,那不壹定是spring事務的鍋,最好確認壹下妳使用的那張表,是否支持事務。7.未開啟事務有時候,事務沒有生效的根本原因是沒有開啟事務。妳看到這句話可能會覺得好笑。開啟事務不是壹個項目中,最最最基本的功能嗎?為什麽還會沒有開啟事務?沒錯,如果項目已經搭建好了,事務功能肯定是有的。但如果妳是在搭建項目demo的時候,只有壹張表,而這張表的事務沒有生效。那麽會是什麽原因造成的呢?當然原因有很多,但沒有開啟事務,這個原因極其容易被忽略。如果妳使用的是springboot項目,那麽妳很幸運。因為springboot通過DataSourceTransactionManagerAutoConfiguration類,已經默默的幫妳開啟了事務。妳所要做的事情很簡單,只需要配置spring.datasource相關參數即可。但如果妳使用的還是傳統的spring項目,則需要在applicationContext.xml文件中,手動配置事務相關參數。如果忘了配置,事務肯定是不會生效的。

  • 上一篇:Redis如何清除JFinal中的緩存?
  • 下一篇:隴南源代碼建設站
  • copyright 2024編程學習大全網