我在Spring Boot(ver 1.4.2)应用程序中有很多计划任务,并希望使用一个处理程序捕获它们的所有异常,就像使用@ExceptionHandler注释的普通控制器一样.由于线程的原因,此方法不适用于使用@Scheduled注释定义的任务:
@Component
public class UpdateJob {
@Transactional
@Scheduled(cron = "0 1 0 * * *")
public void runUpdateUsers() {
userService.updateUsers();
}
@ExceptionHandler
public void handle(Exception e) {
// some more logic here
logger.error(e.getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
@ExceptionHandler不适用于@Scheduled方法(事实证明它并不意味着).相反,Spring Boot使用它自己的LoggingErrorHandler:
2016-12-08 15:49:20.016 ERROR 23119 --- [pool-7-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task.
Run Code Online (Sandbox Code Playgroud)
我可以以某种方式替换或提供计划任务的默认异常处理程序吗?或者它是否有意义(并且可能)切换到PropagatingErrorHandler,据我所知,它会进一步传播错误?有没有其他方法可以仅使用Java配置(没有XML)来实现目标?
这不是这个问题的重复,因为它明确要求基于Java配置而不是XML的解决方案(因此在没有任何XML配置的情况下将其合并到Spring Boot项目中是不错的).
还有一些答案演示了如何从头开始配置TaskScheduler.例如,此答案要求您还定义池大小,最大池大小,队列容量.这是一个解决方案,也需要非常广泛的配置.文档说明了如何配置其他方面,但没有说明如何指定错误处理.但是Java配置所需的最小工作量是什么,这样我才能最大限度地保留Spring Boot默认值(线程池,执行器配置等).
我已经安装春天的@Scheduled有如下其中一个cron表达式,每隔一小时trend.olap.local.loading.cron.expression是0 0 * * * ?.
@Scheduled(cron = "${trend.olap.local.loading.cron.expression}")
public void loadHoulyDataToLocalOlap() {
try {
// To calculate prev hour;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, -1);
Date date = cal.getTime();
int hour = cal.get(Calendar.HOUR_OF_DAY);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Loading hourly data into local olap :" + date
+ ", and hour :" + hour);
}
dataIntegrationProcessor.loadHourlyDataToLocalOlap(hour);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Loading hourly data into local olap :" + date
+ ", and hour :" + hour …Run Code Online (Sandbox Code Playgroud) 我正在构建一个 Springboot 应用程序,我想从前端打开一个预定的方法。(因为我希望调度程序仅在从前端调用该方法后运行)
然后,此计划方法将使用给定参数调用 Web 服务并继续运行,直到收到特定响应(“成功”)。
收到特定响应后,我希望计划的方法停止运行,直到从前端再次调用它。
我不确定如何开始和停止计划方法的执行。
我目前有这个:
@Component
public class ScheduledTasks {
private static final Logger LOG = LoggerFactory.getLogger(ScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void waitForSuccess(String componentName) {
LOG.info("Running at: " + dateFormat.format(new Date()));
String response = MyWebService.checkStatus(componentName);
if ("success".equalsIgnoreCase(response)) {
LOG.info("success");
//Stop scheduling this method
} else {
LOG.info("keep waiting");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的控制器,通过它可以打开预定的方法:
@Controller
public class MainController {
@GetMapping(/start/{componentName})
public @ResponseBody String startExecution(@PathVariable String componentName) {
//do some …Run Code Online (Sandbox Code Playgroud) 有没有办法通过用户交互调用弹簧调度方法(作业)?我需要创建一个显示所有作业的表,用户应该能够手动执行它们。确保作业自动运行,但用户应该能够手动启动它们。
@Configuration
@EnableScheduling
public class ScheduleConfiguration {
@Bean
public ScheduledLockConfiguration taskScheduler(LockProvider
lockProvider) {
return ScheduledLockConfigurationBuilder
.withLockProvider(lockProvider)
.withPoolSize(15)
.withDefaultLockAtMostFor(Duration.ofHours(3))
.build();
}
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
}
@Component
public class MyService {
@Scheduled(fixedRateString = "1000")
@SchedulerLock(name = "MyService.process", lockAtLeastFor = 30000)
@Transactional
public void process() {
// do something
}
}
Run Code Online (Sandbox Code Playgroud) 由于"只有空格返回方法可以注释@Scheduled",当我使用@Bean配置而不是xml配置时,如何使用Spring Batch和Spring Scheduler Task ?您可以在下面找到我的完整配置文件.当我从中触发main()但只有一次时,它运行得很好.我想添加@Scheduled(fixedrate=9999)以便以特定频率唤起相同的工作.据我所知,为了做到这一点,我被期望添加@Scheduledstep1方法,但我不能,因为它返回与void不同.
@Configuration
@EnableBatchProcessing
@EnableScheduling
public class BatchConfiguration {
private static final Logger log = LoggerFactory
.getLogger(BatchConfiguration.class);
@Bean
@StepScope
public FlatFileItemReader<Person> reader() {
log.info(new Date().toString());
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
reader.setResource(new ClassPathResource("test_person_json.js"));
reader.setLineMapper(new DefaultLineMapper<Person>() {
{
setLineTokenizer(new DelimitedLineTokenizer() {
{
setNames(new String[] {"firstName", "lastName" });
}
});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {
{
setTargetType(Person.class);
}
});
}
});
return reader;
}
@Bean
public ItemProcessor<Person, Person> processor() {
return new …Run Code Online (Sandbox Code Playgroud) 我使用sprint boot 1.3,spring 4.2
在这堂课上
@Service
public class PaymentServiceImpl implements PaymentService {
....
@Transactional
@Override
public void processPayment() {
List<Payment> payments = paymentRepository.findDuePayment();
processCreditCardPayment(payments);
}
}
Run Code Online (Sandbox Code Playgroud)
我想每隔x刻拨打一次processPayment.
此x时刻在数据库中设置.用户可以修改它.
所以我想我不能使用anotation.
我开始这样做了
@EntityScan(basePackageClasses = {MyApp.class, Jsr310JpaConverters.class})
@SpringBootApplication
@EnableCaching
@EnableScheduling
public class MyApp {
@Autowired
private DefaultConfigService defaultConfigService;
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
@Bean
public TaskScheduler poolScheduler() {
SimpleAsyncTaskExecutor taskScheduler = new SimpleAsyncTaskExecutor();
DefaultConfigDto defaultConfigDto = defaultConfigService.getByFieldName("payment-cron-task");
String cronTabExpression = "0 0 4 * * ?";
if (defaultConfigDto != …Run Code Online (Sandbox Code Playgroud) 在调试为什么我的@scheduled方法没有触发时,我将问题追溯到ScheduledAnnotationBeanPostProcessor.
当调用afterSingletonsInstantiated()后,applicationContent已经设置,因此不会调用finishRegistration().
然后onApplicationEvent()似乎永远不会被调用.contextRefresh事件正在作为我使用的调用的StartUpHouseKeeping类发布
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) { ... }
Run Code Online (Sandbox Code Playgroud)
如果我在afterSingletonsInstantiated()中坚持一个断点并手动调用finishRegistration()就可以正常工作.
我正在使用java配置而没有web.xml
AppInit.java
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
private static final Logger log = LoggerFactory.getLogger(AppInitializer.class);
private static final String[] NO_CACHE_URLS = new String[]{"*.appcache", "*.webapp", "/static/js/*", "/static/css/*", "/api/*", "/ping"};
public AppInitializer() {
log.info("** App Initializer **");
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
}
@Override
protected WebApplicationContext createRootApplicationContext() {
// ((ConfigurableEnvironment)context.getEnvironment()).addActiveProfile(_env.getProperty("env", "local"));
return super.createRootApplicationContext();
}
@Override …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用@Scheduled注释运行spring批处理作业,如下所示:
@Scheduled(cron = "* * * * * ?")
public void launchMessageDigestMailing() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
jobLauncher.run(messagesDigestMailingJob, new JobParametersBuilder().addDate("execution_date", new Date()).toJobParameters());
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
javax.persistence.TransactionRequiredException: Executing an update/delete query
Run Code Online (Sandbox Code Playgroud)
但是,当我从spring mvc控制器启动作业时,不会发生此错误,如下所示:
@GetMapping("/messageDigestMailing")
public void launchMessageDigestMailing() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
jobLauncher.run(messagesDigestMailingJob, new JobParametersBuilder().addDate("execution_date", new Date()).toJobParameters());
}
Run Code Online (Sandbox Code Playgroud)
我知道Spring批处理事务并且不需要@Transactional/ @EnableTransactionManagement.为什么我会得到上述异常?
我在网上找到的所有样本都使用了ResourcelessTransactionManager(参见https://www.mkyong.com/spring-batch/spring-batch-and-spring-taskscheduler-example),但我确实需要将我的工作执行持续到数据库.
有人可以帮忙吗?
编辑:这是堆栈跟踪(您可以在ItemWriter下面看到弹簧批次):
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query …Run Code Online (Sandbox Code Playgroud) 我的代码中有以下注释
@Scheduled(fixedDelayString = "${app.delay}")
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我必须拥有这样的属性
app.delay=10000 #10 sec
Run Code Online (Sandbox Code Playgroud)
属性文件看起来不可读,因为我已经计算了以毫秒为单位的值。
有没有办法在那里传递 5m 或 30s 之类的值?