我有一些代码只想允许一个线程访问。我知道如何使用以下任一方法来完成此操作 synchronized 块或方法,但这可以在集群环境中工作吗?

目标环境是WebSphere 6.0,集群中有2个节点。

我有一种感觉 synchronized 行不通,因为每个节点上应用程序的每个实例都有自己的 JVM,对吧?

我在这里尝试做的是在系统启动时对数据库记录执行一些更新。它将查找任何早于代码版本的数据库记录,并执行特定任务来更新它们。我只希望一个节点执行这些升级,因为我想确保每个工作项只升级一次,并且这些升级的性能不是一个大问题,因为它只发生在应用程序启动时,并且它只真正执行任何操作自上次启动以来代码已更改的时间。

数据库是DB2v9,我直接通过JNDI(没有ORM层)访问它。

有人建议全局锁可能是这里的方法,但我不确定如何做到这一点。

有没有人在这个领域有任何指示?

谢谢!

有帮助吗?

解决方案

您是正确的,使用 Java 同步结构无法实现跨进程同步。幸运的是,您的问题实际上不是代码同步,而是同步与数据库的交互。

处理这个问题的正确方法是使用数据库级锁。假设您有一些包含数据库架构版本的表,因此您应该确保在启动/升级过程期间锁定该表。

如果您指定了数据库类型(DB2?)和访问方法(原始 sql、jpa 等),那么所涉及的精确 sql/db 调用可能会更清楚。

更新(2009 年 8 月 4 日下午 2:39):我建议 锁表 保存模式版本号的某个表上的语句。这将序列化对该表的访问,防止两个实例同时运行升级代码。

其他提示

是的,你是正确的在同步的块不会在集群工作。其理由是,当你说,每个节点都有其自己的JVM。

有方式,但是,要获得同步块中的簇的工作,因为他们将在单节点的环境中工作。最简单的方法是使用产品如兵马俑,这将处理不同的JVM线程之间的协调,以便正常的并发控制可以在集群中使用。有很多文章解释它是如何工作,如介绍OpenTerracotta

有其他的解决方案,当然。这主要取决于你真正想要在这里实现。我不会用数据库锁,如果你需要的规模,成为DB不同步。但我真的劝你找一个现成的解决方案,因为瞎搞与集群同步凌乱业务:)

可以使用一个内存数据网格状 http://www.hazelcast.com/对于这一点。这是一个分布式数据结构支持锁定。

由于您谈论的是两台机器,因此您甚至没有共享内存,因此无需同步。

我们对数据库做了类似的事情。这是通过在表中添加记录版本控制来实现的。这就是你应该做的,

  1. 添加记录/行版本的列。
  2. 通过逻辑检查记录是否需要更新。
  3. 当您更新记录时,请确保数据库中的记录版本与您拥有的版本相同。
  4. 每次写入数据库时​​都会升级版本。

如果遵循这些规则,您应该只使用一台服务器来更新数据库。

无法你只需锁定更新该表(或整个分贝),因此,当获得的锁的第一个节点的所有其他节点不将能写。后续节点将等待,并且锁被释放时,代码将被更新,从而没有记录更新是必需的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top