簡體   English   中英

跨群集共享Java同步塊,還是使用全局鎖?

[英]Sharing a Java synchronized block across a cluster, or using a global lock?

我有一些代碼,我只想允許一個線程訪問。 我知道如何使用synchronized塊或方法完成此操作,但這是否適用於集群環境?

目標環境是WebSphere 6.0,在集群中有2個節點。

我覺得synchronized不起作用,因為每個節點上的每個應用程序實例都有自己的JVM,對嗎?

我在這里嘗試做的是在系統啟動時對數據庫記錄執行一些更新。 它將查找比代碼版本更舊的任何數據庫記錄,並執行特定任務以更新它們。 我只希望一個節點執行這些升級,因為我想確保每個工作項只升級一次,並且這些升級的性能不是一個大問題,因為它只發生在應用程序啟動時,它只是真正做任何事情自上次啟動以來代碼更改的時間。

數據庫是DB2v9,我通過JNDI直接訪問它(沒有ORM層)。

有人建議全球鎖定可能是這里的方式,但我不知道如何做到這一點。

有沒有人在這個舞台上有任何指針?

謝謝!

是的,你是正確的,因為同步塊不能在群集中工作。 正如您所說,原因是每個節點都有自己的JVM。

但是,有一些方法可以使同步塊在集群中工作,因為它們可以在單節點環境中工作。 最簡單的方法是使用像Terracotta這樣的產品,它將處理不同JVM之間的線程協調,以便可以在整個集群中使用正常的並發控制。 有很多文章解釋了它是如何工作的,比如OpenTerracotta簡介

當然還有其他解決方案。 這主要取決於你真正希望在這里實現的目標。 如果需要擴展,我不會使用數據庫鎖進行同步,因為DB不需要。 但我真的懇請你找到一個現成的解決方案,因為弄亂群集同步是一件混亂的事情:)

您是正確的,跨進程的同步將無法使用Java同步構造。 幸運的是,您的問題實際上不是代碼同步,而是與數據庫同步交互。

處理此問題的正確方法是使用數據庫級別鎖定。 據推測,您有一些包含db模式版本的表,因此您應確保在啟動/升級過程中鎖定該表。

如果您指定了數據庫類型(DB2?)和訪問方法(原始sql,jpa等),那么所涉及的精確sql / db調用可能會更清楚。

更新(2009年8月4日下午2:39) :我建議在一些持有模式版本號的上使用LOCK TABLE語句。 這將序列化對該表的訪問,防止兩個實例同時運行升級代碼。

您也可以使用像http://www.hazelcast.com/這樣的內存數據網格。 這是一種支持鎖定的分布式數據結構。

既然你在談論2台機器,你甚至沒有共享內存,所以沒有什么可以同步的。

我們用我們的數據庫做類似的事情。 這是通過在表中添加記錄版本來實現的。 這是你應該做的,

  1. 添加記錄/行版本列。
  2. 瀏覽邏輯以檢查記錄是否需要更新。
  3. 更新記錄時,請確保DB中的記錄版本與您擁有的記錄版本相同。
  4. 每次寫入數據庫時​​都會更新版本。

如果遵循這些規則,您應該只有一台服務器更新數據庫。

你不能簡單地鎖定表(或整個數據庫)進行更新,所以當獲得鎖的第一個節點時,所有其他節點都無法寫入。 后續節點將等待,並且當釋放鎖時,代碼將被更新,因此不需要記錄更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM