Hibernate驱逐缓存时出现Concurrent Modification exception问题咨询
新用户创建后执行缓存驱逐触发ConcurrentModificationException异常解决方案
根因分析
- 代码中
saveSystemUserProfile为异步调用,方法返回时用户数据的保存事务尚未完成提交,Hibernate仍在持有、操作对应数据库连接资源 - 未等待异步保存操作完成就直接执行缓存驱逐逻辑,
resetTeamListCache方法被事务切面拦截(可从堆栈中的TransactionInterceptor调用逻辑验证),会额外开启Hibernate连接操作,两个并发流程同时修改Hibernate资源注册表中的非线程安全HashMap结构,最终触发并发修改异常
修复方案
等待异步操作完成后再执行缓存驱逐
将异步保存方法的返回值调整为CompletableFuture,等待方法执行完成、事务提交后再执行缓存驱逐,参考代码:
// 调整systemUserProfileManager.saveSystemUserProfile方法返回值为CompletableFuture CompletableFuture<Void> saveFuture = systemUserProfileManager.saveSystemUserProfile(userBasicInfo); saveFuture.join(); // 阻塞等待异步保存操作全流程完成 StartupListener.refreshContext(request.getSession().getServletContext());
移除缓存驱逐方法的多余事务注解
resetTeamListCache仅执行缓存清空逻辑,不需要绑定数据库事务,移除该方法或MyCacheManager类上添加的@Transactional注解,避免调用时开启不必要的Hibernate资源操作,从根源消除资源竞争问题。
确认缓存实现线程安全
如果使用自定义缓存实现,禁止使用非线程安全的HashMap存储缓存数据,改用ConcurrentHashMap等线程安全容器;若使用Spring Cache默认实现,无需额外调整,默认已采用线程安全的存储结构。
内容的提问来源于stack exchange,提问作者ANKIT KUMAR
相关产品推荐
相关产品推荐

