由于系统建设,原两台服务器应用增加到了四台,导致死锁频频发生。在以往两台服务器的情况下,一般很少出现,也就没有关注。最近服务器新增导致死锁现象非常频繁。经过几周的测试分析,终于找到了解决方案。现将分析及解决方案附上:
1.DBA核查数据库各属性参数配置正常
2.查找网络资料,提示所有查询QUARTZ_TRIGGER等表的SQL语句末尾增加with ur,将quartz中源码进行调整,但调整后仍会出现死锁;
3.根据DBA提供的数据,发现我们每个任务都是同一个JOBNAME。加之网络资料提示需要将JOBNAME增加索引的指导,修改代码将每个任务设置不同的JOBNAME。一般情况下无死锁现象,一旦在任务执行期间启动应用,则由于抢占资源等各种原因,死锁造成几何倍增长;
4.再分析死锁SQL以及quartz机制,发现quartz框架中StdRowLockSemaphore类中SELECT * FROM QRTZ_LOCKS WHERE LOCK_NAME = 'TRIGGER_ACCESS' FOR UPDATE并没有对数据上锁,咨询生产运维部DBA,默认的隔离级别是游标读(CS),数据读出来后就释放锁了,需再SQL语句后指定with rs;这个事务隔离与其他数据库(如Oracle)设置不同,一般Oracle数据库试用for update就会形成行级锁,而DB2则不可以。
好了,现在基本定位了,DB2数据库如果没有使用with rs,则为游标锁,使用完毕就会释放。对于DB2的事务控制,请自行搜索或咨询DBA,鄙人也不是特别明白,不做过多解释。
所以最终的解决方案是:对quartz源代码关于StdRowLockSemaphore类的SELECT * FROM QRTZ_LOCKS WHERE LOCK_NAME = 'TRIGGER_ACCESS' FOR UPDATE增加WITH RS,重新打包quartz即可。
另外,请仔细搜索所有的StdRowLockSemaphore类,可能一个项目中存在各种版本的quartz包,需要清理成一个,以免类加载时加载的到了未修改的版本。
我们系统使用的是quartz1.8.5,原则上1.8版本左右的都没有问题,其他版本请自行分析测试。
相关推荐
Quartz是一款开源的作业调度框架,它允许开发者在Java应用程序中定义定时任务。在大型分布式系统中,为了提高系统的容错性和高可用性,通常会采用集群部署的方式。集群中的每个节点都是一个独立的Quartz实例,它们...
在构建Quartz集群时,为了实现高可用性和任务的分布式处理,需要在多个节点之间共享状态信息,这就涉及到数据库的支持。数据库在这里起到了存储作业和触发器信息的作用,确保在集群中的各个节点间能够正确协调和执行...
Quartz是一款开源的作业调度框架,它允许开发者在应用程序中安排任务执行,比如定时执行数据同步、发送邮件等。在Quartz 2.2.3版本中,它提供了内置的数据库表结构脚本来帮助用户在各种不同的数据库系统上设置和管理...
2. **tables_sybase.sql**:适用于Sybase数据库,确保Quartz在Sybase环境下正常工作。 3. **tables_oracle.sql**:专为Oracle数据库定制,包含了在Oracle中部署Quartz所需的SQL语句。 4. **tables_mysql_innodb....
这就要求在集群中的每个节点都配置相同的`quartz.properties`文件,并连接到同一个数据库。 在数据库中,Quartz会创建一系列的表,如`QRTZ_JOBS`, `QRTZ_TRIGGERS`, `QRTZ_CRON_TRIGGERS`等,用于存储job和trigger...
Quartz是一个功能丰富的开源作业调度库,几乎可以集成在任何Java应用程序中 - 从最小的独立应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的计划,以执行数十,数百甚至数万个作业; 将任务定义为标准...
Quartz 2.3.0 版本提供了对多种数据库的支持,包括Oracle、MySQL、DB2等。这个压缩包文件“quartz-2.3.0数据库表SQL.zip”包含了为这些数据库创建和配置Quartz所需的SQL脚本。 1. **Quartz 框架**: - Quartz 框架...
Quartz能够与数据库紧密结合,将任务和触发器的信息存储在数据库中,这样就可以动态地管理和修改任务,而无需重启服务。这为我们的应用程序提供了极大的灵活性,可以在运行时添加、更新或删除任务。 要使用Spring ...
Quartz是一款开源的作业调度框架...总的来说,Quartz的持久化数据库表是实现可靠定时任务调度的关键组成部分,它们提供了一种在系统崩溃或重启后能恢复任务调度的能力,使得Quartz成为许多企业级应用中不可或缺的工具。
Quartz 是一个开源的作业调度框架,广泛应用于Java应用程序中,用于执行定时任务。它支持持久化任务和触发器到数据库,确保即使在系统重启后也能恢复先前的任务安排。本篇将详细介绍Quartz如何实现数据库持久化,并...
在应用启动时,`init`方法会将这两个Bean加入到Quartz调度器中。 当你的应用在集群环境中运行时,每个节点都将拥有相同的任务定义。Quartz的集群支持确保只有一个节点执行特定的作业实例,以防止任务重复执行。通过...
这个压缩包“Quartz.net 3.0.7.0数据库持久化.rar”包含了关于如何使用Quartz.NET实现任务调度的数据库持久化和集群配置的资料。Quartz.NET 3.0.7.0是该库的一个稳定版本,它提供了许多改进和新特性。 **数据库持久...
在"quartz动态从数据库获取时间定时"的场景中,我们可以理解为Quartz的任务执行时间不是硬编码在程序中,而是从数据库中动态获取,这提供了更大的灵活性和可配置性。 首先,让我们来详细了解一下Quartz的核心概念:...
3. **代码实现**:在应用中,创建Scheduler实例,并调用`scheduler.initialize(config)`方法初始化,这里的config是根据配置文件生成的`Properties`对象。 4. **启动集群**:在多个服务器上部署相同的应用实例,...
在集群环境下,需要设置`org.quartz.scheduler.instanceId`为`AUTO`,让Quartz自动分配唯一的实例ID。同时,配置`org.quartz.jobStore.isClustered`为`true`,启用集群功能。 6. **故障转移和恢复**: 当一个正在...
在应用启动时,或者在需要动态更新任务时,调用服务层的方法,将数据库中的任务加载到Quartz的Scheduler中。同时,为了实现任务的动态更新,我们需要监听数据库的变化,一旦有任务信息更新,立即同步到Quartz。这...
### quartz在集群环境下的最终解决方案 #### 背景与挑战 随着系统复杂度的提高以及业务需求的变化,越来越多的应用程序需要支持高可用性和可扩展性。为了满足这些需求,通常会选择将应用程序部署在集群环境中。...
在部署Quartz时,根据选用的数据库(如MySQL、Oracle、SQL Server等),需要将"quartz-数据库建表语句.zip"中的相应SQL脚本运行在数据库上,以创建这些必要的表。这一步是Quartz配置中的关键部分,确保Quartz能够...
Quartz是一款广泛使用的开源任务调度框架,它允许开发者在Java应用程序中定义和执行定时任务。在Quartz中,任务和调度信息存储在数据库中,因此理解如何为不同类型的数据库创建相应的表是至关重要的。以下是对...