2011-09-21 95 views
0

我有一個MySql數據庫實例,其中帳戶表維護餘額字段。我有多個Java應用程序,每個使用Jdbc連接到數據庫,這可能會增加或減少字段的值。我如何確保讀取,計算和更新值,並且此過程是孤立發生的,並且「知道」可能正在執行同一事情的任何其他Java進程?確保多個Java客戶端訪問數據庫時的數據完整性

+0

這就是爲什麼RDBMSs首先被髮明出來的原因。 – Ingo

回答

5

簡單的答案是使用交易: http://dev.mysql.com/doc/refman/5.0/en/commit.html

然而,在你所描述的情況下,我更喜歡不保存的帳戶在表中的列的平衡,但通過總結來計算的話與該賬戶相關的交易的價值。它對你提出的完整性問題不太敏感,而且你不太可能遇到模糊的鎖定方案。

+0

在一個已經有1000年交易的長期賬戶中,你總會總結那些每次都能找到餘額的賬戶嗎?或者有什麼策略可以避免這種情況,比如維持每年的平衡? –

+2

通常,調整良好的數據庫系統並不真正減慢SUM中數百和數十個記錄之間的速度。當然,如果你必須計算出數千個賬戶的餘額,那可能不那麼容易。在這種情況下,我使用了一種類似於您的建議的策略:有效地歸檔歷史交易,並創建與這些歸檔交易總和的「期初餘額」交易。 –

2

一個簡單的方法是JDBC事務管理。請參閱java.sql.Connection.setAutoCommit()文檔。它使您能夠明確禁用自動語句提交:

Connection c = /* retrieve connection */ 
c.setAutoCommit(false); 
c.setTransactionIsolation(/* depends on your requirements */); 
c.executeQuery(/* */); 
c.executeUpdate(/* */); 
c.commit(); /* or c.rollback() */ 

在真實的場景中,你必須引入一個finally塊提交或rolback交易,否則你可能在你的數據庫死鎖結束。

編輯:如果您的Java應用程序是最終用戶客戶端,則用戶總是有風險,即用戶直接連接到數據庫(例如使用Access)繞過您的事務管理邏輯。這是我們開始在兩者之間放置應用程序服務器的原因之一。解決方案也可能是實現存儲過程,以便客戶端根本不與表進行交互。

1

如果您使用的是InnoDB引擎,那麼您可以使用MySQL record level locking鎖定來自其他客戶端的更新的特定帳戶記錄。

更新:替代地,您可以應用程序級鎖描述爲here

+0

從參考手冊 - '死鎖可能...'和'一般來說,表鎖優於行級鎖' - 不會激發信心。您是否使用了行級鎖定,並且使用起來很簡單?你有沒有關於如何使用Jdbc執行「鎖定」的示例代碼?謝謝。 –

相關問題