您在使用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的痛苦相关推荐

  1. Spring测试支持和上下文缓存

    Spring为单元测试和集成测试提供了全面的支持-通过注释来加载Spring应用程序上下文,并与JUnit和TestNG等单元测试框架集成. 由于为每个测试加载大型应用程序上下文需要时间,因此Spri ...

  2. Java缓存框架使用EhCache结合Spring AOP

    Java缓存框架使用EhCache结合Spring AOP 一.Ehcache简介     EhCache是一个纯Java的进程内缓存框架,具有如下特点:     1. 快速简单,非常容易和应用集成. ...

  3. (转)使用 Spring缓存抽象 支持 EhCache 和 Redis 混合部署

    背景:最近项目组在开发本地缓存,其中用到了redis和ehcache,但是在使用注解过程中发现两者会出现冲突,这里给出解决两者冲突的具体方案. spring-ehcache.xml配置: <?x ...

  4. 基于Spring的Web缓存

    缓存的基本思想其实是以空间换时间.我们知道,IO的读写速度相对内存来说是非常比较慢的,通常一个web应用的瓶颈就出现在磁盘IO的读写上.那么,如果我们在内存中建立一个存储区,将数据缓存起来,当浏览器端 ...

  5. spring 测试 事务_Spring陷阱:事务测试被认为是有害的

    spring 测试 事务 Spring杀手级功能之一是容器内集成测试 . 尽管EJB多年来一直缺乏此功能(Java EE 6终于解决了这个问题,但是我尚未进行测试),但是Spring从一开始就允许您从 ...

  6. Spring 测试(第一部分)

    1.Spring Testing介绍 测试是企业软件开发的一个组成部分.本章重点讨论IoC原则为单元测试 unit testing增加的价值,以及Spring框架对集成测试 integration t ...

  7. mybatis教程--查询缓存(一级缓存二级缓存和整合ehcache)

    查询缓存 1 缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题. 2 mybat ...

  8. Spring 3.1缓存抽象教程

    即将发布的Spring 3.1版本中引入的新功能之一是缓存抽象之一 . Spring Framework提供了对将缓存透明添加到现有Spring应用程序中的支持. 与事务支持类似,缓存抽象允许一致使用 ...

  9. [Spring实战系列](5)Spring应用上下文

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/SunnyYoona/article/details/50618337 下面是Spring-Hello ...

最新文章

  1. 电脑音响怎么插_【图片】汽车音响改装案例本田CRV改装德国HELIX汽车音响_汽车音响改装吧...
  2. php 集合安装,centos7安装php5.6报错集合
  3. Myeclipse 创建web项目的一些基本操作
  4. 网页制作中点一张图片变成图片浏览式_如何建设响应式网站?
  5. Mac利用PD虚拟机安装Centos7
  6. 小雷:我的核心定位和远大志向(上次更新2013年11月9日)
  7. 推荐系统概述——《ML算法原理和实践》学习笔记
  8. 【Gym-102059 G】Fascination Street【亏欠型DP思想】
  9. 手把手教你如何获得光学成像系统的PSF(点扩散函数)——从beads成像到处理图像的经验分享
  10. java 实时弹幕_[Java记录]实时抓取斗鱼弹幕
  11. 《iOS移动开发从入门到精通》图书连载2:如何成为一名iOS开发者
  12. 苹果官网下架iPhone 8;破解百度网盘的Pandownload开发者被捕;三大运营商年内上线5G消息 | EA周报...
  13. 学习笔记——3-8译码器实例(FPGA)
  14. 论文结尾参考文献形式
  15. js时间戳转时间(年-月-日 时:分:秒)
  16. 诺基亚 java_诺基亚开放Symbian Javaapps了
  17. GWL30地下水情监测仪
  18. 【PCB开源分享】STC32G12K128/STC8H8K64U开发板
  19. 微型计算机 电脑爱好者,电脑爱好者1994年全.pdf
  20. Css字体中英文对照表

热门文章

  1. 150. 逆波兰表达式求值---JAVA---LeetCode
  2. MyBatis_1 简介
  3. git 在ssh情况下提交代码
  4. 海南计算机网络技术学校,三亚广播电视大学计算机网络技术专业_海南报名_网络教育计算机网络技术专业教学计划_中国教育在线...
  5. 计算机主机组成实验,计算机组成原理实验-运算器组成实验报告
  6. linux入门_Linux超详细0基础入门篇(一)
  7. java 示例_功能Java示例 第2部分–讲故事
  8. gatling的环境配置_将Gatling集成到Gradle构建中–了解SourceSet和配置
  9. jcache_随机JCache内容:多个提供程序和JMX Bean
  10. Kogito人机规则-第1部分:进一步解决流口水