原文地址:http://laolinshi.iteye.com/blog/1453572
近来研究定时器Quartz集群的实现原理时,发现了一种利用数据库锁的方式来实现集群环境下进行并发控制的方式。由于现在的系统多是部署在集群环境中,需要进行并发控制时,这是一种很好的实现方法,现将原理介绍如下:
首先,在数据库中建立一张拥有锁标识的表,建立表的SQL语句如下:
CREATE TABLE TB_LOCKS
-
(
LOCK_NAME VARCHAR2(40) NOT NULL, PRIMARY KEY (LOCK_NAME) - )
表创建好之后,插入一些数据, 这些数据是根据数据库的业务逻辑操作抽象出的系统所拥有的表的类型,如"TRIGGER_ACCESS"就表示对任务触发器相关的信息进行修改删除操作时所需要获得的锁。每当要进行与某种业务相关的数据库操作时,先去这张表中查询操作相关的业务对象所需要的锁,如Quartz中需要修改触发气的状态,下次触发时间时,就需要获得"TRIGGER_ACCESS"所表示的锁。这时,执行查询这个表数据的SQL形如“select * from TB_LOCKS t where t.lock_name='TRIGGER_ACCESS' for update”,在select之后加了“for update”,就如JAVA语言中的为方法加上Symchriozed一样,起到了串形化访问修改所需数据的作用。当一个线程使用上述的SQL对表中的数据执行查询操作时,若查询结果中包含相关的行,数据库就会对这些行进行ROW LOCK。若此时又有另外一个线程使用相同的SQL对表的数据进行查询时,由于查询出的数据行已经被数据库锁住了,此时这个线程就只能等待,直到拥有这些行锁的线程完成了相关的业务操作,执行了commit动作后,数据库才会释放了相关行的锁,这个线程才能继续执行。通过这样的机制,在集群环境下,结合乐观锁的机制就可以防止一个线程对数据库数据的操作的结果被另外一个线程所覆盖,从而可以避免一些难以觉察的错误发生。当然,达到这种效果的前提是需要把Connection设置为手动提交,即autoCommit为false,下面是执行相关步骤的程序代码:
- /**
- * Execute the given callback having optionally aquired the given lock.
- * This uses the non-managed transaction connection.
- *
- * @param lockName The name of the lock to aquire, for example
- * "TRIGGER_ACCESS". If null, then no lock is aquired, but the
- * lockCallback is still executed in a non-managed transaction.
- */
- protected Object executeInNonManagedTXLock(
- String lockName,
- TransactionCallback txCallback) throws JobPersistenceException {
- boolean transOwner = false;
- Connection conn = null;
- try {
- if (lockName != null) {
- if (getLockHandler().requiresConnection()) {
- conn = getNonManagedTXConnection();
- }
- //获得相关的锁,通过带有"for update"的select语句实现,如果这个锁被其他线程占用,执行这个操作的线程只能等待
- transOwner = getLockHandler().obtainLock(conn, lockName);
- }
- if (conn == null) {
- conn = getNonManagedTXConnection();
- }
- Object result = txCallback.execute(conn);//执行相关的业务逻辑操作,获得操作的结果
- commitConnection(conn);//提交操作结果,释放锁
- return result;
- } catch (JobPersistenceException e) {
- rollbackConnection(conn);//撤销操作结果,释放锁
- throw e;
- } catch (RuntimeException e) {
- rollbackConnection(conn);//撤销操作结果,释放锁
- throw new JobPersistenceException("Unexpected runtime exception: "
- + e.getMessage(), e);
- } finally {
- try {
- releaseLock(conn, lockName, transOwner);
- } finally {
- cleanupConnection(conn);
- }
- }
- }
相关推荐
在集群环境下,如果需要在分布式系统中保持单例特性,就需要采取额外的措施。传统的单例模式在多进程或多节点的分布式环境中不再适用,因为每个进程或节点都可以独立创建自己的单例实例。要实现分布式环境下的单例,...
在双机集群环境下实现Oracle并行服务是一项复杂但极具价值的任务。通过合理的规划和实施,不仅可以提高系统的性能和可用性,还可以为企业带来更高的经济效益。未来,随着技术的进步和需求的变化,集群技术将会得到更...
在ISCSI环境下实现集群(应用虚拟化)的过程中,ISCSI技术起到了关键的桥梁作用,它不仅降低了构建存储区域网络(SAN)的成本,还提升了数据安全性和应用灵活性。ISCSI技术,即互联网小型计算机系统接口,是一种允许...
kettle集群(cluster)在多个服务器上并发执行是指通过将kettle部署在多个服务器上,实现分布式数据处理和排序的目的。这种方法可以大大提高数据处理的效率和速度,特别是在大数据量的情况下。 以下是kettle集群在...
本文主要讨论了 Linux 环境下实现负载均衡集群的方法。负载均衡集群可以在多台网络设备之间合理分配业务量,使设备充分发挥其处理能力,得到了广泛应用。 首先,作者介绍了 Tomcat 和 Apache 的局限性。当 Tomcat ...
本文主要探讨了集群环境下并行编程的两种主流模型——PVM(并行虚拟机)和MPI(消息传递接口),并分析了基于这两种模型的多种编程工具的发展状况、编程环境及特性。通过对比这些工具,本文还指出了集群编程环境未来...
本文将深入探讨如何在Spring中配置Quartz以实现集群环境下的任务调度。 首先,我们需要理解Quartz集群的基本概念。在Quartz集群中,多个Quartz服务器共享同一个“作业存储”(Job Store),这个存储可以是关系...
在分布式系统中,集群同步锁是一种重要的机制,用于在多节点间协调操作,确保数据的一致性和完整性。Spring作为一款广泛使用的Java应用框架,提供了多种方式来实现集群同步锁。本篇文章将深入探讨如何利用Spring在...
在构建企业生产环境中的50-100台规模高并发网站集群架构时,我们需要考虑多个关键因素,包括系统的稳定性、可扩展性、安全性以及性能优化。以下将详细阐述搭建过程中涉及的重要知识点。 1. **集群的需求**: - 高...
Linux 是一种开源操作系统,它的核心在于其灵活性和可定制性,使其成为各种场景下的理想选择,包括服务器环境。Linux 的稳定性和安全性使得它在校园网服务器集群中扮演重要角色。 【系统开发】 系统开发在构建校园...
基于Linux平台下的MPI并行PC集群搭建实现 概述:在Linux平台下基于MPI的并行PC集群搭建的实现是高性能计算领域中的热点问题。该文主要介绍了基于Linux平台下的MPI并行PC集群搭建的实现,着重于介绍了集群系统和MPI...
### IBM WAS ND 分布式网络环境的理解与集群的实现 #### 概述 IBM WebSphere Application Server Network Deployment (WAS ND) v6.1 是一款高级的企业级中间件解决方案,旨在支持大规模分布式网络环境下的应用服务...
- 通过集群实现横向扩展,增加服务器数量来处理更多并发。 - 应用服务器集群,通过负载均衡器分配请求,提高处理能力。 - 使用无状态服务设计,使每个节点都能独立处理请求。 7. **异步处理**: - 对于非实时性...
Java + Netty 实现的高并发高可用MQTT服务broker,轻松支持10万并发(有群友实现了130万在线).zip 功能说明: 参考MQTT3.1.1规范实现 完整的QoS服务质量等级实现 遗嘱消息, 保留消息及消息分发重试 心跳机制 MQTT连接...
Zookeeper 的工作基于一种称为“Zab”协议,它通过心跳机制保持节点间的通信,并实现数据同步。Zookeeper 服务器分为 Leader 和 Follower 两种角色,Leader 负责处理所有的写操作,Follower 负责复制 Leader 的数据...
在单机环境中,生成流水号相对简单,但在分布式集群环境下,由于多节点并发处理,就需要解决生成全局唯一流水号的挑战。 一种常见的解决方案是使用全局递增的方式,但这种方法在分布式环境下容易引发竞争条件,可能...
Java + Netty 实现的高并发高可用MQTT服务broker,轻松支持10万并发,已用于生产环境 技术体系:(使用 netty 实现通信及协议解析,使用 nutzboot 提供依赖注入及属性配置,使用 redis 实现消息缓存,集群,使用 ...