我有一些代码,我想只允许访问一个线程。 我知道如何使用既可以实现这个synchronized
块或方法,而是将这项工作在集群环境中?
目标环境是的WebSphere 6.0,与所述簇中2个节点。
我有一种感觉, synchronized
将无法正常工作,因为每个节点上的应用将拥有自己的JVM的每个实例,对不对?
我想在这里做的是进行一些更新数据库记录时,系统启动。 它看起来对于一些老的代码版本的任何数据库记录,并执行特定的任务更新它们。 我只想要一个节点执行这些升级,因为我想确保每个工作项目仅升级一次,这些升级的性能是不是一个大问题,因为它只发生在应用程序启动时,它才真正做任何事情当代码已经因为它启动最后一次改变。
该数据库是DB2v9,并且我直接通过JNDI(无ORM层)对其进行访问。
有人建议,全球锁可能是去这里的路,但我不知道该怎么做。
有没有人有在这个舞台上的指针?
谢谢!
你是正确的,整个过程同步将不使用Java同步构建工作。 幸运的是,你的问题真不是码同步的一个,而是与数据库进行同步互动。
处理这个问题的正确方法是用数据库级锁。 假设您有一个包含数据库架构版本的一些表,所以你应该确保锁定该表的启动时间/升级过程。
如果你指定的数据库类型(DB2?)和访问方法(原始SQL,JPA等)所涉及的精确SQL / DB电话很可能会更加清晰。
更新(2009/8/4下午2:39):我建议LOCK TABLE一些表格持有模式的版本#语句。 这将串行访问该表防止两个实例通过升级代码同时运行。
是的,你是在synchronized块正确也不会在集群中工作。 究其原因,正如你所说的那样,每个节点都有自己的JVM。
有办法,但是,要获得synchronized块在集群环境中工作,因为他们将在单节点环境中工作。 最简单的方法是使用一个产品如陶土 ,这将处理不同的JVM之间线程的协调,以便正常的并发控制可在集群中使用。 有很多文章解释如何工作的,像介绍OpenTerracotta 。
还有其他的解决方案,当然。 这主要取决于你真正想要在这里实现。 我不会用数据库锁,如果你需要的规模,成为DB不同步。 但我真的劝你找一个现成的解决方案,因为瞎搞与集群同步脏活:)
您可以使用内存数据网格状http://www.hazelcast.com/了这一点。 这是一个分布式数据结构支持锁定。
既然你是在谈论2台机器,你甚至不必共享内存所以没有什么可同步。
我们做我们的数据库类似的东西。 这是通过在表中添加记录版本实现。 这是你应该做的,
- 添加记录/行版本列。
- 通过逻辑去检查记录是否需要更新。
- 当您更新记录,确保在数据库记录的版本是一样的,你有什么。
- 每次写入数据库时撞了版本。
您应该只有一台服务器更新数据库,如果你遵循这些规则。
无法您只需锁定更新表(或整个数据库),所以当获得锁的第一个节点的所有其他节点不能将能写。 后续节点会等待,并且锁被释放时,代码将因此将不需要记录更新进行更新。
文章来源: Sharing a Java synchronized block across a cluster, or using a global lock?