2013-07-10 36 views
0

我在嘗試同步多個數據庫,其中的項目具有ID的GUID,這意味着一個項目在所有數據庫上都具有相同的ID。使用hibernate同步2個數據庫 - 使用save(),update()或saveOrUpdate()?

我的問題是: 如果我修改或1個數據庫項目創建,並希望這種變化對其他數據庫同步,我應該:

1)檢查項目是新的或剛修改,如果新的再使用保存()函數,如果它的修改,然後使用update()函數

2)不檢查其新的或修改,並只使用saveOrUpdate()方法的功能?

+0

我可以問......爲什麼?如果您希望數據庫相同,請使用主從複製。如果您只希望跨數據庫共享此特定數據,也許您應該重新考慮您的應用程序設計,以使該數據僅來自一個數據庫?我會向你承諾:只要你在兩個地方存儲相同的數據,它**會**不同步。 –

+0

我有一個服務器上的中央數據庫,ond本地數據庫上的平板電腦不總是有互聯網連接,所以如果1本地數據庫添加或更新項目,然後其轉移到中央的一個,它將其轉移到所有其他 –

+0

啊,好吧,這更有意義。我只會跟蹤客戶端上的「上次更新」和「上次同步」時間。無論何時您建立互聯網連接,請將上次更新的最後一次同步的所有對象都拉出來,然後將它們推送到服務器。(或者,對於服務器到客戶端 - 同樣的事情) –

回答

1

在評論中看到您的用例之後,我認爲最好的方法是跟蹤(在客戶端和服務器上)最近一次更新/最後一次同步時間。如果上次同步時間爲空,或者在上次更新時間之前,您知道數據需要同步。

現在,您的問題的核心:如何同步它。客戶端在向您發送對象時不需要知道服務器的狀態。事實上,它不應該。考慮客戶端發佈一個對象的情況,服務器接收並處理它,但連接在客戶端收到響應之前就會消亡。這是一個非常有效的方案,會導致數據不匹配。因此,試圖確定服務器是否已收到對象(來自客戶端)的任何方式都可能最終處於不良狀態。

最好的解決方案是真正在服務器上創建一個冪等端點(一個upsert方法,或saveOrUpdate,就像您在問題中提到的那樣),它可以確定如何處理該對象。服務器可以通過主鍵查詢它的數據庫,以確定它是否具有該對象。如果有,它可以更新,如果沒有,它可以插入。

可以理解的是,性能和數據一樣重要。但是,堅持使用數據庫中的主鍵,並且添加的另一個選擇查詢應該非常小(小於10毫秒)。如果你真的想擠出更多的性能,你總是可以使用memcache或redis作爲緩存層來確定數據庫中是否有某個GUID。這樣,你只需要打內存(而不是數據庫)來確定一個對象是否存在。它的開銷只能在Web服務器和緩存服務器之間的延遲時間內測量(因爲內存讀取非常便宜)。

TL;博士

的Upsert(或saveOrUpdate)是要走的路。儘量不要追蹤另一臺機器的狀態。

+0

只是爲了澄清,與saveOrUpdate()我的意思是:'Session session = createSessionMethod(); session.saveOrUpdate(item);''我想你錯過了我 –

+0

@ M364M4Ncro的確,這確實改變了事情,我以爲你有自己的方法做這件事。在這種情況下,Hibernate實際上會錯誤地嘗試更新。您將推出一個*確實擁有一個ID(客戶端生成的GUID)的對象。在這種情況下,即使對象可能不存在於服務器中,Hibernate也會執行更新。解決方案很簡單。而不是調用saveOrUpdate,你應該自己嘗試從數據庫中獲取對象。如果你得到一個結果,你可以執行'saveOrUpdate'(或者''update'' - 無關緊要)。如果不是,那麼'persist' –

+0

好的,thx,man,這個在冬眠中保存的東西真的很複雜 –