Spring - 2 个应用程序可以同时使用相同的 @Transactional 服务吗?

Posted

技术标签:

【中文标题】Spring - 2 个应用程序可以同时使用相同的 @Transactional 服务吗?【英文标题】:Spring - Can 2 applications use the same @Transactional service at once? 【发布时间】:2018-05-16 18:56:22 【问题描述】:

我正在开发 2 个 Spring 项目、一个 Web 应用程序和一个独立的后端服务。两者都使用 Hibernate 和相同的底层数据库。由于这两个项目都使用自己的大多数 Service 和 Repository 类的副本,因此我有很多重复的代码,这成为我自己管理总共超过 47000 行代码的噩梦。因此,我决定创建第三个项目,我基本上将其用作类库。它存储实体类、服务类和存储库类,并作为 Maven 依赖项添加到每个项目中。在我做出这个重大改变之前,一切都完美无缺。

Web 应用程序运行良好,但服务根本无法启动。这是堆栈跟踪:

Exception in thread "Test Legacy Orders Server Init Thread" Exception in thread "Test Legacy Formulary Server Init Thread" org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.IllegalStateException: EntityManagerFactory is closed
at org.springframework.orm.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:564)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:474)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:289)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy79.logInfo(Unknown Source)
at com.mdenis.mdhis_service.connectivity.HL7TestServer.start(HL7TestServer.java:69)
at com.mdenis.mdhis_service.core.MDHIS_Service$7.run(MDHIS_Service.java:311)

Caused by: java.lang.IllegalStateException: EntityManagerFactory is closed
at org.hibernate.internal.SessionFactoryImpl.validateNotClosed(SessionFactoryImpl.java:498)
at org.hibernate.internal.SessionFactoryImpl.getCache(SessionFactoryImpl.java:769)
at org.hibernate.internal.AbstractSharedSessionContract.<init>(AbstractSharedSessionContract.java:142)
at org.hibernate.internal.AbstractSessionImpl.<init>(AbstractSessionImpl.java:29)
at org.hibernate.internal.SessionImpl.<init>(SessionImpl.java:252)
at org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1229)
at org.hibernate.internal.SessionFactoryImpl.openSession(SessionFactoryImpl.java:449)
at org.springframework.orm.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:456)
... 9 more

我在 HibernateUtil 类中唯一改变的是这一行:

sessionFactory.setPackagesToScan(new String[] "com.mdenis.mdhis_common.entity");

这是包含共享 jar 文件中的实体的新包。我知道 Hibernate 正在使用新设置正确初始化,因为有事务从该服务成功通过数据库。我注意到的一件事是主线程似乎很好。此应用程序是高度多线程的,并且似乎只有子线程会遇到此问题。

在我进行大规模重构之前,每个项目都有自己的本地 @Transactional 服务类可供使用,并且一切运行良好。我在做什么是不允许的吗?有没有办法让 2 个项目使用相同的 @Transactional 服务?

谢谢!

【问题讨论】:

【参考方案1】:

哇,想出了这个。实体管理器已关闭,主线程由于缺少 bean 而出错。我解决了这个问题,一切正常,今天的代码足够了!

【讨论】:

以上是关于Spring - 2 个应用程序可以同时使用相同的 @Transactional 服务吗?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何在同一spring应用程序中同时添加JWT和基本身份验证?

在 Spring 中读取 2 个具有相同变量名的属性文件

Spring的Bean管理(注解)四个相同功能的注解

改造 2 和 Spring RestController

在不同 Tomcat 中具有 2 个 Spring 应用程序的 SSO

49个spring常见面试题