【问题标题】:Spring boot quartz schema other than public doesn't work公共以外的 Spring Boot 石英模式不起作用
【发布时间】:2024-01-21 06:00:01
【问题描述】:

我无法为石英表使用其他模式(公共模式除外)。这是我的石英设置:

spring.quartz.job-store-type=jdbc
spring.quartz.jdbc.initialize-schema=always
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
spring.quartz.properties.org.quartz.jobStore.isClustered=true
spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=2000
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
spring.quartz.properties.org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.useProperties=false
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_

和配置类:

@Bean
public SchedulerFactoryBean schedulerFactory(ApplicationContext applicationContext, DataSource dataSource, QuartzProperties quartzProperties) {
    SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
    AutowireCapableBeanJobFactory jobFactory = new AutowireCapableBeanJobFactory(applicationContext.getAutowireCapableBeanFactory());
    Properties properties = new Properties();
    properties.putAll(quartzProperties.getProperties());

    schedulerFactoryBean.setOverwriteExistingJobs(true);
    schedulerFactoryBean.setDataSource(dataSource);
    schedulerFactoryBean.setQuartzProperties(properties);
    schedulerFactoryBean.setJobFactory(jobFactory);

    return schedulerFactoryBean;
}

@Bean
public Scheduler scheduler(ApplicationContext applicationContext, DataSource dataSource, QuartzProperties quartzProperties)
    throws SchedulerException {
    Scheduler scheduler = schedulerFactory(applicationContext, dataSource, quartzProperties).getScheduler();
    scheduler.start();
    return scheduler;
}

这可以正常工作,并且正在创建表。但是,我希望将表放在不同的模式中。所以我将石英设置为使用“石英”模式。

spring.quartz.properties.org.quartz.jobStore.tablePrefix=quartz.QRTZ_

这是我得到的错误:

[ClusterManager: Error managing cluster: Failure obtaining db row lock: ERROR: current transaction is aborted, commands ignored until end of transaction block] [org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: ERROR: current transaction is aborted, commands ignored until end of transaction block

关于如何解决它的任何想法?

【问题讨论】:

    标签: java spring-boot quartz-scheduler quartz


    【解决方案1】:

    大胆希望“tablePrefix”也可以调整“db schema”,(并且没有关于“db schema”的documented property),但是如果你在数据源上配置它,你会更幸运. 即,您将为应用程序使用的每个用户/模式引入/配置不同的(spring)数据源(bean)...

    ,那么您将 wire 具有适当数据源 (quartz) 的调度程序工厂。

    schedulerFactoryBean.setDataSource(quartzDataSource);
    

    或者通过(@Autowired)参数注入,或者方法调用:@Bean initialization - difference between parameter injection vs. direct method access?

    更新(关于“接线”):

    ..来自current spring-boot doc:

    要让 Quartz 使用 DataSource 除了应用程序的主 DataSource,声明一个 DataSourcebean,用 @QuartzDataSource 注释它的 @Bean 方法。这样做可确保 SchedulerFactoryBean 和模式初始化都使用 Quartz 特定的 DataSource。 同样,要让 Quartz 使用 TransactionManager 而不是应用程序的 main ...声明一个 TransactionManager bean,...@QuartzTransactionManager


    您可以通过自定义获得更多控制权:

    spring.quartz.jdbc.initialize-schema 
    Database schema initialization mode.
    default: embedded (embedded|always|never)
    
    spring.quartz.jdbc.schema 
    Path to the SQL file to use to initialize the database schema.
    default: classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql
    

    ...属性,其中@@platform@@ 指的是您的数据库供应商。

    但这对您的要求没有用...因为looking at 并遵守原始方案 - 它们似乎独立/免费。 (因此,数据源方法看起来更有前途。)

    参考:

    【讨论】:

    • 我赞成您的回答,因为它带来了有价值的信息。尽管如此,我还是从堆栈溢出研究中得到了 tablePrefix=schema.tablePrefix 的想法,它似乎适用于其他人。例如。 *.com/questions/64045340/… 找不到确切的例子。也许有人找到了解决方法
    • 感谢您的支持和有趣的事实! ...我尝试过,但没有足够强调:所有这些用户/模式/数据源“事物”都是非常特定于供应商的。 (数据源)default_schema + 初始化细节当然是相关的。 .. 您在什么(类型)数据库上运行?
    • 并且(再次查看built-in schemes)我们必须意识到除QRTZ_ 之外的任何其他table_prefix 都应该失败(使用该脚本)
    • 我正在使用 postgres。我什至看到有人使用 Quartz.NET,并说使用 tablePrefix 的“hack”有效。
    • 找到了解决方法。会让flyway在不同的schema中创建脚本,留下tablePrefix=schema.QRTZ_。用作魅力
    【解决方案2】:

    所以这个想法是 Quartz 不使用 spring.quartz.properties.org.quartz.jobStore.tablePrefix 创建表

    表名是静态的。例如 qrtz_triggers。正如@xerx593 指出的那样。

    我们可以做的是在不同的架构中创建表(手动、flyway、liquibase),更新 tablePrefix=schema.qrtz_ 并且它会起作用。

    用 Postgres 测试

    【讨论】:

      最近更新 更多