`
tigers
  • 浏览: 33853 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

基于Quartz的高频率同步

    博客分类:
  • J2EE
阅读更多
quartz是一个按照设定的时间规则来调度作业的调度器,比如可以设定每30s启动一个Job,但如果Job在30s内还未完成,那么quartz默认情况下还是按照设定的周期启动新的Job线程。

有这样一个应用场景,两个表结构相同的数据库A和B,A是一个实时交易的业务系统数据库,需要把A中的数据完全准实时的复制到B中。同时,交易表中存在一个时间戳字段,同步任务是每次按照这个时间戳来作增量同步的,即先在B中select max(col_timestamp)得到当前最大时间戳,再到A中获取大于该时间戳的数据集,最后再insert到B中。

在该场景下,如果前一个线程还未结束写的动作(比如一共1000条记录,已经提交了500条,还剩500条没提交),而后一个现成又开始读的话,将导致后500条记录重复插入的异常。实现的代码是完全的JDBC代码,不支持跨数据库级别的事务管理,而Job中第一次读和后面的写是在数据库B中,可以合并为一个事务(t1),第二次读是针对数据库A,作为一个事务(t2)。为了避免以上的幻读和重复写异常,可以这样作:
(1)将connection的自动提交设为false。
(2)设置事务隔离级别为serialization。事务t1肯定要设置为最高级别serialization的,因为要避免幻读(避免当前一个线程还在写的时候,后续的线程来读);而事务t2可以不用把隔离级别设为serialization,默认的read commited即可。
(3)每次把当前需要insert的数据作为一次性提交,也就是说第一次的读和后面的写作为一个事务而不是多个。

这样即时数据量再大,而同步周期再短,数据都能顺利的复制到目标库。

回过头来看整个流程,其实在数据库级别加serialization隔离级别,就是使得事务能够串行处理。理论上来说,这种效果其实在应用程序层面也是可以做到的,即后面的线程在前面的线程处理完成之后再启动,也就是所谓的状态化线程控制,但quartz似乎并不支持这一点。
分享到:
评论
12 楼 dayang2001911 2008-11-04  
用quartz的statefuljob这个接口是么?
我想问问用这个可以保证不并发吗?怎么我测试这个JOB并且设定按照每分钟触发一次,不会阻塞并发运行呢?
public class AAAAJob implements StatefulJob {


/**
* @param context .
* @throws JobExecutionException .
*/
public void execute(JobExecutionContext context)
throws JobExecutionException {
try {
int count=0;
while(true){
log.info("count:"+(count++));
}
} catch (Exception ex) {
ex.printStackTrace();

}
}
}
11 楼 duobin3000 2008-06-27  

瞎说,
qutarz有这样的实现,而且spring-qutarz也提供了这样的功能:
<property name="concurrent" value="false" />
10 楼 e-ant 2008-02-18  
我解决这个问题,是用了一个全局变量,来注释上一个job是否提交完成
每个job定时调度时,先判断上个job是否提交完成,完成则进行数据库操作,否则终止job
9 楼 simbasun 2008-02-15  
StatefulJob 是正解...

StatefulJob instances follow slightly different rules from regular Job instances. The key difference is that their associated JobDataMap is re-persisted after every execution of the job, thus preserving state for the next execution. The other difference is that stateful jobs are not allowed to execute concurrently, which means new triggers that occur before the completion of the execute(xx) method will be delayed.
8 楼 ddandyy 2008-02-15  
所以我说的是你那个是病句.........
首先你就给quartz定义为"按照设定的时间规则来调度作业的调度器" 而他实际上不只是这个, 其次你后面说的是"每30s启动一个Job"这个很明显是指的循环调用方式 而不是定时方式

P.S: 这个没什么好说的吧  在数据库加一个状态控制就实事了 第2个启动 发现状态还是启动中 就中止
7 楼 tigers 2008-02-15  
ddandyy 写道
引用
quartz是一个按照设定的时间规则来调度作业的调度器,比如可以设定每30s启动一个Job,但如果Job在30s内还未完成,那么quartz默认情况下还是按照设定的周期启动新的Job线程。


这个应该是一个病句
就我说知quartz的两种调用方式 一种定时运行 一种循环运行
定时运行不考虑前一个是否执行完毕  循环运行当前一个没执行完的情况下  是不会启动下一个job的

两年前专门test过这个东西......现在应该不会变吧.....这种基础的东西

对,是两种方式,但现在说的是定时方式,你说的手工循环方式没错,但我们不是在讨论它
6 楼 tigers 2008-02-15  
抛出异常的爱 写道
事务的颗度太大是你的问题根源....
你把所有的1000条数据都读出来了...
如果你不是一次读出所有的数据
那么你的问题是很简单的.
当第二个quartz起来时把前一个业务结束.

问题是事务的粒度不是同步本身能够控制的,而是由业务需求确定的。从系统的健壮性来看,即使数据粒度再小,也不能保证在网络和机器处理能力等因素影响下能在设定的固定周期内完成事务,所以还是得从系统本身考虑,无论从quartz的线程控制级别还是jdbc事务级别。
5 楼 tigers 2008-02-15  
statefuljob确实可以考虑,从实验来看,它是等待上一个周期的运行实例结束之后再启动下一个周期的实例,但问题如果实例运行持续的时间很长,比如是周期的10倍,那么quartz启动的是当前时间的实例还是补上这10个周期内没启动的实例呢?

从实验结果来看,我把周期设为1秒,同时向源库中循环插入100000条记录,同步结束耗时78s,实例起了48个,从而推测上面的问题答案应该是启动当前时间周期的实例,而之前的忽略。但察看实例的启动时间,发现问题似乎并不完全这样,当时间间隔很小的事情下,quartz会连续把之前没启动的实例在某个周期内连续“补”回来,这一点让人费解,难道线程控制当真如此诡异?
4 楼 Godlikeme 2008-02-13  
可以控制job非并发执行,参考 javadoc org.quartz.StatefulJob。
3 楼 jones 2008-02-13  
嘿嘿,job实现StatefulJob接口就可以了,还是多看看API吧
2 楼 ddandyy 2008-02-13  
引用
quartz是一个按照设定的时间规则来调度作业的调度器,比如可以设定每30s启动一个Job,但如果Job在30s内还未完成,那么quartz默认情况下还是按照设定的周期启动新的Job线程。


这个应该是一个病句
就我说知quartz的两种调用方式 一种定时运行 一种循环运行
定时运行不考虑前一个是否执行完毕  循环运行当前一个没执行完的情况下  是不会启动下一个job的

两年前专门test过这个东西......现在应该不会变吧.....这种基础的东西
1 楼 抛出异常的爱 2008-02-13  
事务的颗度太大是你的问题根源....
你把所有的1000条数据都读出来了...
如果你不是一次读出所有的数据
那么你的问题是很简单的.
当第二个quartz起来时把前一个业务结束.

相关推荐

    quartz集群各种数据库建表脚本

    基于quartz2.2.1版本,这个脚本应该包含了创建必要的调度表,如QRTZ_JOB_DETAILS、QRTZ_TRIGGERS、QRTZ_SIMPLE_TRIGGERS等,这些表用于存储任务的详细信息、触发器信息以及相关的简单触发器信息。 QRTZ_JOB_DETAILS...

    任务管理API quartz

    Quartz常用于定时任务场景,例如发送邮件通知、数据同步、定期备份、系统维护等。通过灵活的调度策略,开发者可以轻松实现复杂的时间控制需求。 总结,Quartz是一个强大且灵活的任务调度框架,其API提供了丰富的...

    Spring Quartz集成

    在实际项目中,Spring Quartz集成可以用于各种场景,如定时数据同步、报表生成、系统维护等。通过Spring的AOP(面向切面编程)和依赖注入特性,我们可以轻松地将定时任务与业务逻辑解耦,提高代码的可读性和可维护性...

    maven ssh+ quartz + zookeeper 实现分布式任务调度的管理界面

    在这个场景中,我们关注的是一个基于Maven、SSH(Spring、Struts2、Hibernate)框架、Quartz定时任务库以及Zookeeper协调服务的实现。这个系统提供了对分布式任务调度的管理界面,使得任务的创建、监控和管理变得...

    Quartz 时间定时执行框架

    Quartz时间定时执行框架是...Quartz的灵活性和强大功能使其成为企业级应用中任务调度的首选方案,无论是在处理后台任务、数据同步、定时报告生成还是其他任何需要定时操作的场景中,Quartz都能提供稳定而可靠的支撑。

    spring+quartz定时任务

    每个任务可以有不同的执行频率和时间策略,通过Quartz的集群功能,还可以保证任务在多台服务器上的高可用性和负载均衡。 总结,Spring与Quartz的结合为开发者提供了强大的定时任务管理能力,无论是简单的单任务还是...

    Quartz 2D刷帧Demo

    Quartz 2D支持多种图形操作,包括线条、形状、路径、渐变、阴影、图像处理等,它基于PDF矢量图形模型,意味着你可以绘制出无损缩放的高质量图形。 2. **CADisplayLink与刷帧** 在这个Demo中,可能使用了`...

    Quartz API

    Quartz API 是一个开源的作业调度框架,广泛用于Java应用程序中,用于自动化任务执行,如定时触发业务逻辑、数据同步或其他后台服务操作。这个框架以其灵活性、可扩展性和稳定性著称,使得开发者能够轻松地创建、...

    51单片机课程设计--基于51单片机开发系统的PCB电路板.docx

    知识点:时钟芯片的选择对整个系统的时序和同步性能有着重要影响,需要根据具体的应用场景和设计要求选择合适的时钟芯片。 5. 硬件设计考虑因素:文档中讨论了硬件设计的考虑因素,包括电路板的设计、布线、组件...

    Spring排程(Scheduling)技术

    Spring 排程(Scheduling)技术是Spring框架中用于实现定时任务的重要功能,它允许开发者在应用程序中安排任务定期执行,以满足各种自动化需求,如数据同步、日志清理、定时报告生成等。排程技术的核心在于管理和...

    基于QCM传感器的凝血分析仪电路模块设计

    高精度的6M有源晶振通过时钟芯片CDCV304被分为8个独立的时钟信号,这些信号送至差频器74LS74的CLK端,确保每个通道的同步性。经过差频处理后的信号进入EPM570GT100C3芯片,这是一款可编程逻辑器件,通过编程实现频率...

    定时器demo

    【定时器Demo】是一个基于Java实现的简单定时任务示例,它主要展示了如何利用Java的定时器类(java.util.Timer)或定时任务框架(如Quartz、Spring Scheduler)来执行周期性的任务。在这个demo中,开发者可能创建了...

    电子-一种电化学阻抗和石英微天平联用的分析装置及方法

    石英晶体微天平则是一种高精度的质量测量工具,其工作原理基于石英晶片在质量变化时频率的变化。当有分子吸附到或脱附自石英晶片表面时,晶片的质量会发生改变,进而导致其振动频率的变化。QCM被广泛应用于检测薄膜...

    elastic-job-dangdang

    Elastic-Job是基于 Quartz 和 ZooKeeper 的分布式作业调度框架,由两个子项目组成:Elastic-Job-Lite 和 Elastic-Job-Cloud。Elastic-Job-Lite 适用于微服务架构,而 Elastic-Job-Cloud 更适合大规模云计算环境。...

    Epson QMEMS晶体振荡器SG-3030JF数据手册.zip

    1. **QMEMS技术**:QMEMS(Quartz Micro Electro Mechanical Systems)是一种将微电子和微机械技术相结合的技术,用于制造高精度、高性能的晶体振荡器。Epson在QMEMS领域有深厚的技术积累,这使得其产品具有卓越的...

    maximo系统中corn任务设置

    - 在Java编程环境中,Cron任务通常基于Spring框架的`@Scheduled`注解或Quartz库来实现。在Maximo系统中,Cron任务是通过继承`SimpleCronTask`类来创建的。例如,你可以创建一个名为`JDTes`的Java类,该类扩展了`...

    3. spring版 timer HelloWorld

    `TaskScheduler`接口提供了一系列的方法来安排未来的任务执行,而`ThreadPoolTaskScheduler`则是一个基于线程池的实现,可以更好地管理并发执行的任务。 现在,让我们逐步解析“3. Spring版 timer HelloWorld”的...

    ELSSpringSchedulerService

    在Java开发中,定时任务是一种常见的需求,用于执行周期性的任务,如数据同步、报表生成等。Spring框架以其强大的功能和灵活性,成为了Java开发的首选。而在Spring生态中,ELSSpringSchedulerService是一个专门用于...

Global site tag (gtag.js) - Google Analytics