在集群环境中部署的SpringWeb应用中Java并发锁失败

在集群环境中部署的SpringWeb应用中Java并发锁失败,java,multithreading,spring,cluster-computing,Java,Multithreading,Spring,Cluster Computing,在我的SpringWeb应用程序中,我有一个服务方法,其中包含一个由锁保护的代码块。 一次只能有一个线程进入代码块。 这在非集群环境中工作正常,但在集群环境中失败。在集群环境中,节点内会发生同步,但在不同节点之间,代码块会并行执行。这是因为在每个节点中创建了一个单独的锁对象吗? 有人能给我建议吗 代码示例 //Service Class @Service class MyServiceClass { private final Lock globalLock; @Autowired publ

在我的SpringWeb应用程序中,我有一个服务方法,其中包含一个由锁保护的代码块。 一次只能有一个线程进入代码块。 这在非集群环境中工作正常,但在集群环境中失败。在集群环境中,节点内会发生同步,但在不同节点之间,代码块会并行执行。这是因为在每个节点中创建了一个单独的锁对象吗? 有人能给我建议吗

代码示例

//Service Class
@Service
class MyServiceClass {

private final Lock globalLock;

@Autowired
public MyServiceClass(@Qualifier("globalLock") final Lock globalLock){
    this.globalLock = globalLock;
}

public void myServiceMethod(){
    ...
    globalLock.lock();
    try {
        ...
    }
    finally {
        globalLock.unlock();
    }
    ...

}

}//End of MyServiceClass


//Spring Configuration XML
<bean id="globalLock" class="java.util.concurrent.locks.ReentrantLock" scope="singleton" />
//服务类
@服务
类MyServiceClass{
专用最终锁globalLock;
@自动连线
公共MyServiceClass(@Qualifier(“globalLock”)最终锁globalLock){
this.globalLock=globalLock;
}
public void myServiceMethod(){
...
globalLock.lock();
试一试{
...
}
最后{
globalLock.unlock();
}
...
}
}//MyServiceClass的结束
//Spring配置XML

如果您希望在集群环境中同步对象,这意味着涉及许多虚拟机,那么您的解决方案将涉及涉及不同虚拟机之间的某种通信

在这种情况下,完成这件事需要一些想象力:您需要在某个对象上实现互斥,该对象对于所有涉及的VM都是通用的,并且当您将其他机器放入集群时,互斥可能会升级。您是否考虑过一些基于JNDI的解决方案?这里你有一些东西,但我恐怕这看起来有点像学术讨论:

总是有机会实现基于DB机制的东西(总是认为您的DB是集群中所有节点的中心和公共资源)。您可以根据数据库中实现的某种
selectforupdate
机制,在一些仅用于同步的表上设计一些东西


你有一个有趣的问题!:)祝你好运,你是对的,原因是每个节点都有自己的锁。为了解决这个问题,考虑在数据库中引入一个表<代码> Service EyLoos,包含列服务类名称、服务ID、锁定状态和获取时间戳。 对于服务Id,使用
UUID.randomUUID()
使每个服务生成一个唯一的分布式Id

要获取锁,请发出更新以尝试获取它,然后查询它以查看您是否拥有锁。但不要选择、检查然后更新。不应考虑超过一定时间的锁

这是到的实现,其中获取应用程序级悲观锁以锁定共享资源

根据服务上的业务逻辑和您使用的事务管理器的类型,可以选择将服务方法的隔离级别提高到
REPEATABLE\u READ


对于不涉及数据库的解决方案,请查看基于并发模型的分布式并发处理框架-(单击“远程处理”按钮)。

通过“选择更新”进行锁定。谢谢你的解决方案