Quartz是怎样将job持久化到数据库的
作者:互联网
Quartz在QRTZ_JOB_DETAILS表中存储了什么
因为本文章是说明Quartz在QRTZ_JOB_DETAILS表中存储了什么的,所以本篇文章的前提是quartz的配置中是使用了jdbcjobstore的,并且driver代理这里我们使用的是StdJDBCDelegate。
1.QRTZ_JOB_DETAIL表
这张表是quartz存储job的表,按字面意思这些字段分别为
SCHED_NAME:计划名字
JOB_NAME:工作名字
JOB_GROUP:工作组
DESCRIPTION:描述
JOB_CLASS_NAME:工作类名字
IS_DURABLE:是否持久化
IS_NONCONCURRENT:是否同步
IS_UPDATE_DATA:是否更新数据
REQUESTS_RECOVERY:是否要求唤醒
JOB_DATA:job数据
现在我们了解了这些字段的名字,但是我们不知到这些字段里面有什么。所以接下来我们要去了解一下quartz在这些字段中存储了什么。
2. StdJDBCDelegate
/**
* <p>
* Insert the job detail record.
* </p>
*
* @param conn
* the DB Connection
* @param job
* the job to insert
* @return number of rows inserted
* @throws IOException
* if there were problems serializing the JobDataMap
*/
public int insertJobDetail(Connection conn, JobDetail job)
throws IOException, SQLException {
ByteArrayOutputStream baos = serializeJobData(job.getJobDataMap());
PreparedStatement ps = null;
int insertResult = 0;
try {
ps = conn.prepareStatement(rtp(INSERT_JOB_DETAIL));
ps.setString(1, job.getKey().getName());
ps.setString(2, job.getKey().getGroup());
ps.setString(3, job.getDescription());
ps.setString(4, job.getJobClass().getName());
setBoolean(ps, 5, job.isDurable());
setBoolean(ps, 6, job.isConcurrentExectionDisallowed());
setBoolean(ps, 7, job.isPersistJobDataAfterExecution());
setBoolean(ps, 8, job.requestsRecovery());
setBytes(ps, 9, baos);
insertResult = ps.executeUpdate();
} finally {
closeStatement(ps);
}
return insertResult;
}
这是我从quartz的源码StdJDBCDelegate类中发现的,因为我们的driver代理用的就是StdJDBCDelegate,所以往数据库中插入job的应该就是这个方法。
其中我们可以发现,QRTZ_JOB_DETAIL表中的大部分字段都可以在这里找到,除了SCHED_NAME和JOB_DATA字段没有其他都有了,那这两个字段都是存了什么呢?
接下来我们打开插入job的sql语句看看(点击PreparedStatement方法中的参数就可以看到):
String INSERT_JOB_DETAIL = "INSERT INTO "
+ TABLE_PREFIX_SUBST + TABLE_JOB_DETAILS + " ("
+ COL_SCHEDULER_NAME + ", " + COL_JOB_NAME
+ ", " + COL_JOB_GROUP + ", " + COL_DESCRIPTION + ", "
+ COL_JOB_CLASS + ", " + COL_IS_DURABLE + ", "
+ COL_IS_NONCONCURRENT + ", " + COL_IS_UPDATE_DATA + ", "
+ COL_REQUESTS_RECOVERY + ", "
+ COL_JOB_DATAMAP + ") " + " VALUES(" + SCHED_NAME_SUBST + ", ?, ?, ?, ?, ?, ?, ?, ?, ?)";
这里我们发现SCHED_NAME字段的内容是已经在sql中预设好的与job没有什么关联,所以这里我们不去深究,接下来是JOB_DATA字段里面是什么呢?让我们回到原先的insertJobDetail方法中,在执行语句前有一个setBytes方法,其中有两个参数一个是9,另一个是job的jobDataMap的输出流。QRTZ_JOB_DETAIL表中有10个字段,去掉SCHED_NAME,还剩9个,所以我们可以推断出JOB_DATA字段中存储的就是jobDataMap里面的数据。
其他8个字段中JOB_NAME和JOB_GROUP我就不说了,大家应该可以知道是什么。其他6个字段我们一一点进JobDetai类中看看是什么。
这里我是翻译的英文注释
DESCRIPTION:返回对创建者对job实例的描述(如果有的话)。所以显而易见,这个属性对job没什么大用,他只是类似于对这个job实例的注释而已。
JOB_CLASS_NAME:获得将要执行的job实例(这里的注释讲的不是很明白,但是根据代码我们可以知道,个字段存储的是当前我们实现的job类的包路径)
IS_DURABLE:job完成后(没有trigger指向他)是否要保留数据库记录
IS_NONCONCURRENT:关联的job类是否有DisallowConcurrentExecution注解,被标注的job类不能同时执行多个实例
IS_UPDATE_DATA:关联的job类是否有DisallowConcurrentExecution注解,被标注的job类在执行期间会更新jobDataMap中的数据,并且将更新后的jobDataMap数据重新储存到数据库
REQUESTS_RECOVERY:在当前job尚未执行时,当前quartz节点在宕机重启或者故障转移后是否还要执行该job。
至此说明完毕,仅代表个人观点,如有疑问可以在评论区回复。
标签:ps,Quartz,NAME,JOB,化到,job,字段,COL 来源: https://blog.csdn.net/weixin_48872249/article/details/111768630