- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
一、初始化数据库11张quartz表:qrtz_*
先从官网下载好quartz2.3.0包:http://www.quartz-scheduler.org/downloads/
解压后进入目录:quartz-2.3.0-SNAPSHOT\src\org\quartz\impl\jdbcjobstore
得到22种数据库的11张qrtz_*表的初始化SQL,这里列举几个经典的数据库文件:tables_oracle.sql、tables_mysql_innodb.sql、tables_sqlServer.sql、tables_postgres.sql
二、配置定时器quartz.properties
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName=TestScheduler
#instance_1 更改后缀数字后,程序可以执行不同ID的调度器,启动多个调度器,有利于观察其中一个实例宕机后,另外实例恢复这个实例的job任务情况
org.quartz.scheduler.instanceId=instance_1
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=5
org.quartz.threadPool.threadPriority=5
#============================================================================
# 配置Oracle数据库,命名dataSource为myDS
#============================================================================
# 支持PostgreSQL数据库
#org.quartz.dataSource.myDS.driver=org.postgresql.Driver
#org.quartz.dataSource.myDS.URL=jdbc:postgresql://localhost:5432/quartz
org.quartz.dataSource.myDS.driver=oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL=jdbc:oracle:thin:@localhost:1521:orcl
org.quartz.dataSource.myDS.user=zhuwen
org.quartz.dataSource.myDS.password=ZHUwen12
org.quartz.dataSource.myDS.maxConnections=5
org.quartz.dataSource.myDS.validationQuery=select 0 FROM DUAL
#============================================================================
# 配置job任务存储策略,指定一个叫myDS的dataSource
#============================================================================
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
# 支持PostgreSQL数据库
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
# 支持Oracle数据库
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties=false
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
三、job任务类
第一个job类:SimpleRecoveryJob
package org.quartz.examples.example13;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
/**
* 一个愚蠢的作业实现,用于单元测试。
*/
public class SimpleRecoveryJob implements Job {
private static Logger LOG = LoggerFactory.getLogger(SimpleRecoveryJob.class);
private static final String COUNT = "count";
//必须要有public修饰的无参构造函数
public SimpleRecoveryJob() {
}
//任务执行方法
public void execute(JobExecutionContext context) throws JobExecutionException {
JobKey jobKey = context.getJobDetail().getKey();
// 如果作业正在恢复。如果由于“恢复”情况而重新执行作业,此方法将返回true。
if (context.isRecovering()) {
// LOG.info("恢复作业:SimpleRecoveryJob: " + jobKey + " RECOVERING at " + new Date());
System.err.println("恢复作业:SimpleRecoveryJob: " + jobKey + " RECOVERING at " + new Date());
} else {
// LOG.info("不恢复作业:SimpleRecoveryJob: " + jobKey + " starting at " + new Date());
System.err.println("不恢复作业:SimpleRecoveryJob: " + jobKey + " starting at " + new Date());
}
// 睡眠10秒
long delay = 10L * 1000L;
try {
Thread.sleep(delay);
} catch (Exception e) {
//
}
JobDataMap data = context.getJobDetail().getJobDataMap();
int count;
if (data.containsKey(COUNT)) {
count = data.getInt(COUNT);
} else {
count = 0;
}
count++;
data.put(COUNT, count);
LOG.info("SimpleRecoveryJob: " + jobKey + " done at " + new Date() + "\n Execution" + count);
}
}
下面是第二个job类,注意这个job类不允许多线程并发执行:
package org.quartz.examples.example13;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.PersistJobDataAfterExecution;
/**
* 这个作业具有与SimpleRecoveryJob相同的功能,只是这个作业实现是“有状态的”,
* 因为它将在每次执行之后自动重新持久化它的数据(JobDataMap),并且一次只能执行JobDetail的一个实例。
*
*/
@PersistJobDataAfterExecution //持久化JobDataMap里的数据,使下一个定时任务还能获取到这些值
@DisallowConcurrentExecution //禁止并发多任务执行,所以永远只有一个任务在执行中
public class SimpleRecoveryStatefulJob extends SimpleRecoveryJob {
public SimpleRecoveryStatefulJob() {
super();
}
}
四、任务调度类
package org.quartz.examples.example13;
import static org.quartz.DateBuilder.futureDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 用于测试/显示JDBCJobStore (JobStoreTX或JobStoreCMT)的集群特性。
* <p>
* 所有实例必须使用不同的属性文件,因为它们的实例id必须不同,但是所有其他属性应该相同。
* </p>
* <p>
* 如果您希望它清除现有的作业&触发器,设置clearJobs=true
* </p>
* <p>
* 您可能需要先清空残留的表数据,因为将来自非集群设置的数据与集群设置的数据混合在一起可能是不好的。
* </p>
* <p>
* 你可以在运行多个Scheduler实例的时候,杀死其中一个实例,并确保其余实例恢复正在进行的作业。注意,使用默认设置检测故障可能需要15秒左右的时间。
* </p>
* <p>
* 还可以尝试使用/不使用调度程序注册的shutdown-hook插件运行它。(org.quartz.plugins.management.ShutdownHookPlugin)。
* </p>
* <p>
* 注意:从不要在单独的机器上运行集群,除非它们的时钟使用某种形式的时间同步服务(例如NTP守护进程)进行同步。
* </p>
*/
public class ClusterExample {
private static Logger LOG = LoggerFactory.getLogger(ClusterExample.class);
public void run(boolean inClearJobs, boolean inScheduleJobs) throws Exception {
// 初始化调度器
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
if (inClearJobs) {
LOG.warn("***** 删除已存在的job任务和triggers触发器。Deleting existing jobs/triggers *****");
sched.clear();
}
if (inScheduleJobs) {
LOG.info("------- Scheduling Jobs ------------------");
String schedId = sched.getSchedulerInstanceId();
// ========================================================
// ============ job1
// ========================================================
int count = 1;
JobDetail job = newJob(SimpleRecoveryJob.class).withIdentity("job_" + count, schedId).requestRecovery() // 如果job执行过程中宕机,则job重新执行
.build();
SimpleTrigger trigger = newTrigger().withIdentity("triger_" + count, schedId)
.startAt(futureDate(1, IntervalUnit.SECOND))
.withSchedule(simpleSchedule().withRepeatCount(20).withIntervalInSeconds(5)).build();
LOG.info(job.getKey() + " will run at: " + trigger.getNextFireTime() + " and repeat: "
+ trigger.getRepeatCount() + " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");
sched.scheduleJob(job, trigger);
// ========================================================
// ============ job2
// ========================================================
count++;
job = newJob(SimpleRecoveryJob.class).withIdentity("job_" + count, schedId).requestRecovery() // 如果job执行过程中宕机,则job重新执行
.build();
trigger = newTrigger().withIdentity("triger_" + count, schedId).startAt(futureDate(2, IntervalUnit.SECOND))
.withSchedule(simpleSchedule().withRepeatCount(20).withIntervalInSeconds(5)).build();
LOG.info(job.getKey() + " will run at: " + trigger.getNextFireTime() + " and repeat: "
+ trigger.getRepeatCount() + " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");
sched.scheduleJob(job, trigger);
// ========================================================
// ============ job3,这里使用的是job子类SimpleRecoveryStatefulJob
// ========================================================
count++;
job = newJob(SimpleRecoveryStatefulJob.class).withIdentity("job_" + count, schedId).requestRecovery() // 如果job执行过程中宕机,则job重新执行
.build();
trigger = newTrigger().withIdentity("triger_" + count, schedId).startAt(futureDate(1, IntervalUnit.SECOND))
.withSchedule(simpleSchedule().withRepeatCount(20).withIntervalInSeconds(3)).build();
LOG.info(job.getKey() + " will run at: " + trigger.getNextFireTime() + " and repeat: "
+ trigger.getRepeatCount() + " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");
sched.scheduleJob(job, trigger);
// ========================================================
// ============ job4
// ========================================================
count++;
job = newJob(SimpleRecoveryJob.class).withIdentity("job_" + count, schedId).requestRecovery() // 如果job执行过程中宕机,则job重新执行
.build();
trigger = newTrigger().withIdentity("triger_" + count, schedId).startAt(futureDate(1, IntervalUnit.SECOND))
.withSchedule(simpleSchedule().withRepeatCount(20).withIntervalInSeconds(4)).build();
LOG.info(job.getKey() + " will run at: " + trigger.getNextFireTime() + " & repeat: "
+ trigger.getRepeatCount() + "/" + trigger.getRepeatInterval());
sched.scheduleJob(job, trigger);
// ========================================================
// ============ job5
// ========================================================
count++;
job = newJob(SimpleRecoveryJob.class).withIdentity("job_" + count, schedId).requestRecovery() // 如果job执行过程中宕机,则job重新执行
.build();
trigger = newTrigger().withIdentity("triger_" + count, schedId).startAt(futureDate(1, IntervalUnit.SECOND))
.withSchedule(simpleSchedule().withRepeatCount(20).withIntervalInMilliseconds(4500L)).build();
LOG.info(job.getKey() + " will run at: " + trigger.getNextFireTime() + " & repeat: "
+ trigger.getRepeatCount() + "/" + trigger.getRepeatInterval());
sched.scheduleJob(job, trigger);
}
sched.start();
LOG.info("------- Waiting for one hour... ----------");
try {
Thread.sleep(3600L * 1000L);
} catch (Exception e) {
//
}
sched.shutdown();
LOG.info("------- Shutdown Complete ----------------");
}
public static void main(String[] args) throws Exception {
boolean clearJobs = false;
boolean scheduleJobs = true;
for (String arg : args) {
if (arg.equalsIgnoreCase("clearJobs")) {
clearJobs = true;
} else if (arg.equalsIgnoreCase("dontScheduleJobs")) {
scheduleJobs = false;
}
}
clearJobs = true;
scheduleJobs = true;
ClusterExample example = new ClusterExample();
example.run(clearJobs, scheduleJobs);
}
}
概述 触发器是 MySQL 的数据库对象之一,不需要程序调用或手工启动,而是由事件来触发、激活,从而实现执行,包括 INSERT 语句、UPDATE 语句和 DELETE 语句 创建触发器 1. 创建
当我为单元格获得的值是某种类型时,我试图设置一个触发器来显示文本块。 我已经成功地设法在相同的情况下显示图像,但在这种情况下我不需要图像,而是一些文本。 已注释掉行以进行测试。尝试使其工作。注释掉的代
我需要在 phpmyadmin 中为 2 个表创建一个触发器。 所以有表 stores 和 tbl_storefinder_stores。 我想从 stores 表中插入 4 个东西(名称、地址、经度
阅读目录 1、触发器 2、触发器类型 3、触发器语法 4、插入数据触发器案例 5、修改数据触发器案例
SQLite 触发器(Trigger) SQLite 的触发器是数据库的回调函数,它会在指定的数据库事件发生时自动执行/调用。以下是关于SQLite的触发器的要点:SQLite **触发器(Trig
请帮我写一个向表中添加新行的触发器。 我的数据库中有 3 个表: 地区(id,名字); id - 主要; 技术人员(身份证、姓名); id - 主要; 可用性(id、区域、技术、计数); id - p
我正在编写一个触发器来审核表中的更新和删除。我正在使用 SQL Server 2008 我的问题是, 有没有办法在不经过删除和插入表的选择阶段的情况下找出对记录采取的操作? 另一个问题是,如果记录被删
我的表: TableA (id number, state number) TableB (id number, tableAId number, state number) TableC (id n
我很少写触发器。我可以帮助设置这件事。 CREATE TRIGGER audit_tableName ON dbo.tableNameAudit AFTER CREATE, UPDATE, DELET
我之前从未在 Oracle 中创建过触发器,所以我正在寻找一些方向。 如果 ID 不在插入语句中,我想创建一个将 ID 增加 1 的触发器。 ID 应该从 10000 开始,当插入一条记录时,下一个
考虑以下两个(假设的)表 温度 * day * time * lake_name * station * temperature_f 温度_总结 * day * lake_name * station
如何在 SQL 触发器中获取更新记录的值 - 如下所示: CREATE TRIGGER TR_UpdateNew ON Users AFTER UPDATE AS BEGIN S
我是 Cassandra 新手,使用 Cassandra 3.10 并有类似的表格 create table db1.table1 (id text, trip_id text, event_time
在 MSSQL 中执行 TRUNCATE(而不是删除)时如何触发触发器 最佳答案 来自msdn : TRUNCATE TABLE cannot activate a trigger because t
我正在尝试在 sql developer 中创建一个简单的触发器,以在工资发生变化时显示工资的变化 CREATE OR REPLACE TRIGGER salary_changes BEFORE DE
我有三个表: Table1: Customers (CustomerId, Name, CustomerAddress) Table2: AccountManagers(ManagerId, Name
在 Sql Server 2005 触发器中有没有办法在执行期间获取触发器附加到的表的名称和架构? 最佳答案 SELECT OBJECT_NAME(parent_id) AS [Table],
使用 MySQL 5.5,以下触发器因错误而被拒绝: create trigger nodups before insert on `category-category` for each row b
我使用 fancybox 打开一个带有表单的弹出窗口。目前,当鼠标离开主页时,弹出窗口就会出现。为了完成这项工作,我有一个隐藏的链接标签,我用trigger()函数模拟它,单击该函数,以便该链接的hr
我的触发器触发 INSERT, UPDATE and DELETE .我需要根据触发触发器的操作从适当的内存表( inserted, deleted )插入。由于只有 inserted位于 INSER
我是一名优秀的程序员,十分优秀!