这是在here中再次提出的类似问题,这看起来是@Schdeuled不能与@Transaction一起使用的问题。 但是,这有点不同,可能是我的代码处理事务的问题。
我正在运行每天启动的调度程序(DailyScheduler.processDailyScheduler())并因以下错误而失败
SQL错误:17008,SQLState:08003 javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException:无法执行 查询 org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692) 在 org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) 在 org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:492) 引起:java.sql.SQLRecoverableException:Closed Connection:next
我还有一个控制器(DailyController.processDailyJob),它完全执行相同的工作,但是当我使用相同的输入运行时,它会成功。
我不明白为什么我的调度程序无法通过且控制器始终有效。
对此的任何帮助将不胜感激! 谢谢!
DailyScheduler:
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class DailyScheduler {
@Autowired
DailyService dailyService;
@Scheduled(cron = "${daily.scheduler.cron}")
public void processDailyScheduler() {
log.info("DailyScheduler starts");
dailyService.processDailyJob(new Date());
log.info("DailyScheduler finishes");
}
}
DailyController:
@Slf4j
@RestController
@ApiIgnore
public class DailyController {
@Autowired
DailyService dailyService;
@RequestMapping(value = {"/v1/daily/job/{jobDate}"}, method = RequestMethod.POST)
public ResponseEntity<String> processDailyJob(@PathVariable("jobDate") String jobDate,
@RequestHeader(SIFAuthorization.AUTHORIZATION) String authorizationToken)
throws Exception {
SimpleDateFormat dateFormatter =new SimpleDateFormat("dd-MMM-yyyy");
Date targetDate =dateFormatter.parse(jobDate);
dailyService.processDailyJob(targetDate);
return new ResponseEntity<>("Daily Job Processed.", HttpStatus.OK);
}
}
DailyServiceImpl:
@Slf4j
@Service
public class DailyServiceImpl implements DailyService {
@Autowired
private UserServiceRepository userServiceRepository;
@Override
public Integer processDailyJob(Date targetDate) {
userServiceRepository.findUser(targetDate);
}
}
UserServiceRepository:
@Transactional(readOnly = true)
public interface UserServiceRepository extends JpaRepository<UserDailySummary, String> {
UserDailySummary findUser(Date targetDate);
}
的DBConfig:
@Configuration
@Profile("!test")
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "dbEntityManagerFactory",
transactionManagerRef = "dbTransactionManager",
basePackages = {"com.org.dub.mmm"})
@EnableConfigurationProperties(DbProperties.class)
@Slf4j
public class DatabaseConfig {
@Autowired
private DbProperties dbProperties;
@Bean(name = "dataSource")
@Primary
public DataSource dataSource() {
PoolProperties poolProperties = new PoolProperties();
poolProperties.setUrl(dbProperties.getJdbcUrl());
poolProperties.setDriverClassName(dbProperties.getDriverClassName());
poolProperties.setUsername(dbProperties.getUser());
poolProperties.setPassword(dbProperties.getPassword());
// override the default value
poolProperties.setTestOnBorrow(true);
poolProperties.setTestWhileIdle(true);
poolProperties.setValidationQuery(dbProperties.getValidationQuery());
poolProperties.setRemoveAbandoned(true);
DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource(poolProperties);
return dataSource;
}
@Bean
PlatformTransactionManager dbTransactionManager() {
return new JpaTransactionManager(dbEntityManagerFactory().getObject());
}
@Bean
@Primary
LocalContainerEntityManagerFactoryBean dbEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = null;
HibernateJpaVendorAdapter vendorAdapter =
new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.ORACLE);
factoryBean = new LocalContainerEntityManagerFactoryBean();
DataSource dataSource = dataSource();
factoryBean.setDataSource(dataSource);
factoryBean.setJpaVendorAdapter(vendorAdapter);
factoryBean.setJpaProperties(additionalJpaProperties());
factoryBean.setPackagesToScan(new String[]{"com.org.dub.mmm.domain"});
factoryBean.afterPropertiesSet();
return factoryBean;
}
Properties additionalJpaProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.setProperty("hibernate.cache.use_second_level_cache", "true");
properties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");
return properties;
}
}
答案 0 :(得分:1)
我认为问题与标志removeAbandoned=true
有关。此属性与另一个属性removeAbandonedTimeout
结合使用。引用有关的参考:
(int)可以删除放弃(使用中)连接之前的超时(以秒为单位)。默认值为60(60秒)。该值应设置为应用程序可能具有的最长运行查询。
所以看起来你的所有abbandoned
连接都会在1分钟后删除。