日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring测试上下文缓存+ AspectJ @Transactional + Ehcache的痛苦

發布時間:2023/12/3 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring测试上下文缓存+ AspectJ @Transactional + Ehcache的痛苦 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

您在使用AspectJ @Transactionals和Spring嗎? 您是否有多個SessionFactory,也許一個用于嵌入式數據庫進行單元測試,一個用于實際數據庫進行集成測試? 您是否遇到這些例外之一?

org.springframework.transaction.CannotCreateTransactionException:無法打開Hibernate Session進行事務處理。 嵌套的異常是org.hibernate.service.UnknownServiceException:請求了未知的服務

要么

net.sf.ehcache.Cache.isKeyInCache(Cache.java:3068)的org.hibernate.cache.ehcache.internal.regions.EhcacheDataRegion.contains(EhcacheDataRegion.java:223)上的java.lang.NullPointerException

然后,您遇到了一個問題,其中多個緩存的應用程序上下文相互踩在一起。 這篇博客文章將描述一些解決我們遇到的問題的策略。

背景

Spring的Text Context框架默認嘗試通過緩存容器來最小化spring容器必須啟動的次數。 如果您正在運行全部使用相同配置的多個測試,則只需為所有測試創建一次容器,而無需在每次測試之前創建容器。 如果您要進行1000次測試,并且容器需要10到15秒的啟動時間,那么構建/測試時間就會大為不同。

僅當每個人(您和您使用的所有庫)都避免使用靜態字段(全局狀態)時,這才有效,不幸的是,在某些情況下,這是很難/不可能避免的,即使spring違反了此規定! 導致我們出現問題的幾個地方:

  • Spring AspectJ @事務支持
  • EhCache緩存管理器

方面是設計上的單例。 Spring使用它來放置對BeanFactory和PlatformTransactionManager的引用。 如果您有多個帶有各自“自己的” AnnotationTransactionAspect的容器,則它們實際上共享AnnotationTransactionAspect,而最后啟動的容器是“贏家”,從而導致各種意外的難以調試的問題。

Ehcache在這里也很痛苦。 ehcache庫維護它在VM中創建的所有緩存管理器的靜態列表。 因此,如果要使用多個容器,它們將共享對同一緩存的引用。 Spring Test提供了一種機制來指示該測試已“污染”了容器并需要創建它。 這意味著在完成測試類后會破壞容器。 很好,但是如果您的容器具有其他容器共享的對象,則銷毀該共享對象會破壞其他容器。

解決方案

最簡單的解決方案是基本上完全禁用應用程序上下文緩存。 只需在每個測試上放置@DirtiesContext即可完成此操作,或者(最好)您可能應該使用超級類(“抽象測試夾具”)來組織您的測試,在這種情況下,只需在基類上添加@DirtiesContext。 不幸的是,您還失去了所有緩存優勢,并且構建時間將增加。

彈簧容器沒有“清理自身”的通用機制,因為跨容器共享狀態肯定是一種反模式。 他們自己這樣做(AnnotationTransactionAspect,EhCacheManagerFactoryBean.setShared(true)等),這表明他們可能應該添加一些支持。 如果要繼續緩存,則第1步是確保您的代碼中不使用任何“靜態字段”單例。 還要確保將要寫入的所有外部資源分開,以便多個容器可以共存于同一JVM中。

為了解決AspectJ問題,我發現的最佳解決方案是創建一個TestExecutionListener,以在測試執行之前“重置” AnnotationTransactionAspect以指向正確的bean工廠和PTM。 這種偵聽器的代碼在本要點中 。

然后,要使用偵聽器,請將@TestListeners放在基類測試夾具上,以便所有測試都使用新的偵聽器運行。 請注意,使用@TestListeners批注時,必須指定所有執行偵聽器,包括現有的Spring偵聽器。 要點有一個例子。

Ehcache的解決方法是不允許在容器之間共享CacheManager實例。 為此,您必須確保所有緩存管理器都有唯一的名稱。 實際上,這很容易配置。

@org.springframework.context.annotation.Configuration public class CacheBeans {private static final AtomicInteger cacheCounter = new AtomicInteger(0);@Beanpublic EhCacheManagerFactoryBean ecmfb() {EhCacheManagerFactoryBean ecmfb = new EhCacheManagerFactoryBean();// cannot share the cache managersecmfb.setShared(false);// if you are using ehcache.xml on the classpath then there's nothing more to do than just make it // a unique name. If you are using a different config file then use ecmfb.setConfigLocation()ecmfb.setCacheManagerName("ehCache-" + cacheCounter.incrementAndGet());return ecmfb;}// more @Bean defs }

相關問題

以下是一些涉及此問題的Spring jira問題的鏈接:

https://jira.spring.io/browse/SPR-6121

https://jira.spring.io/browse/SPR-6353

翻譯自: https://www.javacodegeeks.com/2014/04/spring-test-context-caching-aspectj-transactional-ehcache-pain.html

總結

以上是生活随笔為你收集整理的Spring测试上下文缓存+ AspectJ @Transactional + Ehcache的痛苦的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。