我们有一个应用程序,我们正在从Spring Boot 1和Hibernate 3.6.8迁移到最新的Spring Boot 2和Hibernate 5.2.17。
一切似乎都没问题,除了我们正在调用一些方法并且没有注入事务。喜欢这项服务:
@Service
public class BreakFixProcessorBO extends BaseProcessorBO {
@Transactional
public void process(String xml){
[...]
它是从这个其他类调用的:
@Service
public class BreakFixAmerInternalConsumer extends BaseConsumer {
private BreakFixProcessorBO breakFixProcessorBO;
@Autowired
public BreakFixAmerInternalConsumer(BreakFixProcessorBO breakFixProcessorBO) {
this.breakFixProcessorBO = breakFixProcessorBO;
}
@Override
protected void proccess(String messageBody) {
breakFixProcessorBO.process(messageBody);
}
许多其他代码调用存储库使用@Transactional,许多服务也使用@Transactional,其中许多服务正常工作。除了其中一些不是,我们找不到任何区别。我一直在阅读很多关于事务如何在代理类上工作的文档。并且似乎当类实现接口行为时会发生一些变化。所以我试着用这个方法创建一个接口:
public interface BreakFixProcessorBO_TransactionTest {
void process(String xml);
}
并有服务实现它:
@Service
public class BreakFixProcessorBO extends BaseProcessorBO implements BreakFixProcessorBO_TransactionTest {
无所谓我们做什么。我们对某些特定服务有以下例外情况:
Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3505) ~[hibernate-core-5.2.17.Final.jar!/:5.2.17.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1427) ~[hibernate-core-5.2.17.Final.jar!/:5.2.17.Final]
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1423) ~[hibernate-core-5.2.17.Final.jar!/:5.2.17.Final]
at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:147) ~[spring-orm-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95) ~[spring-orm-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:96) ~[spring-tx-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:922) ~[spring-tx-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:730) ~[spring-tx-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714) ~[spring-tx-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:532) ~[spring-tx-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304) ~[spring-tx-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at d.s.a.bizo.processor.BreakFixProcessorBO$$EnhancerBySpringCGLIB$$e171e8a9.process(<generated>) ~[classes/:na]
at d.s.a.consumer.BreakFixAmerInternalConsumer.proccess(BreakFixAmerInternalConsumer.java:25) ~[classes/:na]
at d.s.a.consumer.BaseConsumer.onMessage(BaseConsumer.java:16) ~[classes/:na]
at d.s.a.consumer.BreakFixAmerInternalConsumer.onMessage(BreakFixAmerInternalConsumer.java:31) ~[classes/:na]
at sun.reflect.GeneratedMethodAccessor218.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:181) ~[spring-messaging-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:114) ~[spring-messaging-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:51) ~[spring-rabbit-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:182) ~[spring-rabbit-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]
... 10 common frames omitted
似乎Spring AOP成功代理了实例......但是没有创建任何事务。我尝试过Propagation.REQUIRES_NEW,它的行为相同。
我们的PlatformTransactionManager与我们的数据源一起定义:
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@EnableAspectJAutoProxy(proxyTargetClass = true)
@RefreshScope
public class DBConfiguration extends DatabaseConfiguration implements EnvironmentAware {
@Primary
@Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean annotationSessionFactoryBean = new LocalSessionFactoryBean();
annotationSessionFactoryBean.setDataSource(dataSource());
annotationSessionFactoryBean.setPackagesToScan("d.s.a");
annotationSessionFactoryBean.setHibernateProperties(hibernateProperties());
return annotationSessionFactoryBean;
}
@Primary
@Bean
public DataSource dataSource() {
return createDataSource(propertyResolver);
}
@Primary
@Bean
public PlatformTransactionManager transactionManager() {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory().getObject());
return txManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
我们的应用程序使用大多数自动配置:
@SpringBootApplication
@EnableAutoConfiguration(
exclude = {
JmsAutoConfiguration.class,
CamelAutoConfiguration.class
})
@ImportResource({"classpath:/META-INF/spring/applicationContext.xml"})
@ComponentScan(basePackages = "d.s.a")
public class OurApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
public static void main(String[] args) {
if(System.getProperty("debug") != null) { //-Ddebug=true should be a feature
args = Arrays.copyOf(args, args.length+1);
args[args.length-1] = "--debug";
}
SpringApplication.run(OurApplication.class, args);
}
}
applicationContext.xml只是我们尚未迁移的一些旧任务运行器定义。我们缺少什么,还是Spring bug?
你有没有尝试过
@Override
@Transactional
protected void proccess(String messageBody) {
breakFixProcessorBO.process(messageBody);
}