实现应用程序级别的锁定

5
我们的应用程序要求在访问/修改资源之前需要将其锁定,以避免并发操作并保持完整性。由于对该资源进行一系列操作,我们决定实现应用程序级别的锁定概念,所有访问该资源的组件都必须遵守。
请注意,由于多个进程会访问/修改资源,因此同步成为了负担。这也是选择应用程序级锁定的原因之一。
我们考虑实现应用程序级锁定的方法之一是在数据库表中插入和更新条目,该表将具有资源名称、锁定类型(读取锁定、写入锁定或完全排他锁定)以及获取锁定的过程的信息等列。 我们选择数据库表作为选项,因为它是所有访问资源的进程集中的唯一组件,但如果有人能够调查其他可能性,那么这将很有帮助。
使用数据库方法的另一个问题是实现必须使用悲观锁定。(我们的应用程序使用Oracle作为我们的数据库服务器)
此问题的目的是探索实施应用程序级锁定的各种方法。
编辑1:
我提到数据库方法必须实现悲观锁定的原因是:
1.通过用户动态添加访问/修改的各种应用程序组件的资源,因此在这个数据库中始终插入它们的条目将非常难看。
2.即使在此表中添加了资源条目,仍会出现删除这些条目的问题。
乐观锁定方法可能很好,但我无法想出如何实现它。
编辑2:
添加有关锁定类型的详细信息
我已更新上述问题陈述以指定3种锁定类型:
1.读锁定-如果所有其他锁定都是读取或写入,则可以获取该锁定
2.写独占锁-如果所有其他锁定都是读取,则可以获取该锁定
3.完全排他锁定-如果此资源上没有锁,则可以获取该锁定

2
你正在开发什么类型的应用程序(Web/GUI/CLI等)?使用哪种编程语言? - Teekin
这是一个部署在Glassfish集群上的Web应用程序。该应用程序使用Java编程语言开发。 - Andy Dufresne
1个回答

3

在设计数据库锁时,您可能考虑添加一个当前时间的附加字段。您也可以考虑达成一致,即应用程序的任何操作不能超过X个时间单位。

建议背后的原因是为了防止可能发生应用程序崩溃、与数据库失去连接等情况,并且无法“撤消”锁定。其他应用程序将包括删除过期锁并创建新锁的功能。

您还可以要求应用程序插入该列,然后等待随机时间再次尝试检查它。这有助于减少应用程序在等待数据库完成操作时发生资源冲突的可能性。


你在编辑中提到了“我们何时删除这些行?” 这也是第二段落上面的重点 - 当应用程序发出锁定时,让应用程序删除过期的锁定。 第三段旨在防止两个应用程序在完全相同的时间尝试锁定相同资源时可能出现的竞争条件。 随机化时间以及对锁定的第二次检查可以防止同时访问。 - tamarintech
我已更新问题描述,以指定锁类型的详细信息。很抱歉后来添加了这些信息。您能否解释一下:1. 应用程序何时更新时间戳列?2. 当不同的应用程序删除过期锁并创建新锁的同时,是否会出现竞争条件,并且同时有一个请求在该资源上进行锁定。3. 在您的第三段中,提到应用程序插入了一列。这个新列是用来做什么的? - Andy Dufresne
在非常基本的层面上,我所设想的是这样的:应用程序启动后,会向数据库插入一行信息,包括应用程序的PID、应用程序名称(可读性强)和锁定时间戳。然后,它会等待1到5秒钟之间的随机时间。在此期间,它会检查是否有其他程序比已插入的程序更早地请求了锁。如果是,则删除锁定请求并进入睡眠状态以便稍后重试。否则,它将认为自己是唯一的锁定应用程序,并开始执行工作。这应该有助于减少由于与数据库的延迟而导致的竞争条件。 - tamarintech
谢谢分享您的想法。我有几个后续问题(我将分批在评论中添加)。 1.由于资源是动态添加到软件中的,因此当添加资源时,应用程序将不得不在此lock_resource表中插入一行。如果在此时未插入它,则在运行时确定是否需要插入/更新行会出现问题。在我看来,lock_resource表包含以下列 - 资源ID,进程信息,读锁数,写锁数,完整锁数和时间戳。...继续。 - Andy Dufresne
首先,上述考虑存在各种问题,比如在添加资源时需要将一行插入到lock_resource表中进行同步。即,如果添加资源失败,则需要回滚对lock表中行的插入。从软件中删除资源需要删除lock_resource表中相应的行。我不确定Oracle锁定框架是否会在插入和删除期间锁定lock_resource表,因为这会破坏我们乐观锁定的目的。 - Andy Dufresne
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接