分布式锁定与javaee

分布式锁定与javaee,java,concurrency,jakarta-ee,jboss6.x,Java,Concurrency,Jakarta Ee,Jboss6.x,我正在使用JBoss AS 6编写一个Java EE应用程序,我有一个资源,需要对给定参数的方法进行独占访问(与第三方软件的某些接口)。目前,我很淘气(自从),使用java.util.concurrent.ReentrantLock来处理锁定 现在,我将多个JBoss应用程序服务器集群在一起,因此我需要一个跨集群中不同节点工作的解决方案。我想我至少有以下几种选择 共享缓存(Infinispan) 基于文件系统的锁定(可能很糟糕,但我们仍然依赖共享文件系统) 数据库 是什么 理想情况下,我正在寻

我正在使用JBoss AS 6编写一个Java EE应用程序,我有一个资源,需要对给定参数的方法进行独占访问(与第三方软件的某些接口)。目前,我很淘气(自从),使用
java.util.concurrent.ReentrantLock
来处理锁定

现在,我将多个JBoss应用程序服务器集群在一起,因此我需要一个跨集群中不同节点工作的解决方案。我想我至少有以下几种选择

  • 共享缓存(Infinispan)
  • 基于文件系统的锁定(可能很糟糕,但我们仍然依赖共享文件系统)
  • 数据库
  • 是什么
  • 理想情况下,我正在寻找一个高级API,这样我就可以编写像这样的EJB方法

    public class MyEJBBean {
    
        private SharedLock lock;
    
        public void doSomethingWithSharedResource(String s) {
            lock.lock(); // blocks until shared resource is not used by anyone else
            try {
               // Use shared resource
            } 
            finally {
               lock.unlock();
            }
        }
    

    我是否错过了任何选择?有没有人有过这种可以共享的锁定机制的经验?

    理想情况下,我建议将第三方软件包装到一个单独的应用程序中,只在一个实例上运行。通过这种方式,您可以使用EJB单例处理锁定(我相信
    @Singleton
    在您的场景中对您没有帮助),并使用远程EJB/WS公开它。看起来这个软件有点讨厌(单线程?),所以拥有更友好的EJB接口将是一个额外的好处

    想想看——如果你一次只能访问整个系统的库一次,为什么还要分发它呢?无论如何,最多只能有一个实例能够使用

    如果您想坚持使用同构分布式系统(一般来说这不是一个坏主意),我建议使用
    SELECT FOR UPDATE
    锁定数据库。我从未尝试过,但我认为在使用库之前发出这样的SQL(获取锁),然后让EJB容器提交事务(有效地释放锁)就可以了? 它是分布式系统上一种非常轻的文件系统,是实现锁的良好解决方案


    请参见:

    我们以前使用过数据库锁定技术。如果有一个DB实例支持集群,那么这是一种非常有效、廉价的锁定方法。另一个想法是将第三方服务例程放在JMS队列的另一端。请求被发布到队列中,服务对其进行操作,然后通过附加到消息(或其他)的临时队列将结果发布回来。显然,仍然存在锁定,但它在JMS服务器中,在您的应用程序中不再是一流的概念。+1,使用单个使用者的JMS似乎是最简单的方式,我喜欢。它比这稍微复杂一些。API有一个方法foo(字符串s)-该方法不能同时用相同的s调用两次。听起来是个不错的建议,所以我明天上班的时候会好好考虑一下。