2014-05-09 25 views
-1

我的公司從Cerner Multum獲取Microsoft Access數據庫,這需要根據我們的生產後端(即Sybase(12.0.1.3924))進行區分。雖然我意識到現成的數據庫差異工具(http://www.diffkit.org/,http://www.liquibase.org/),但似乎沒有一個符合我的需要 - 因此,我決定編寫一個Java工具來執行作爲概念驗證的工作。多線程數據庫比較的正確方法

目前的情況是,該工具目前正在按設計,和這裏的程序:

  1. 獲取表的列表從一個配置文件
  2. 顯示差異,建立雙方後端連接
  3. 確保在配置文件中的表可以針對這兩個MS訪問和Sybase
  4. 如果是這樣相匹配,使用diff進行:
    • 對於每個表:
      • 獲取從MS Access一排,通過反射實例化對象
      • 遍歷行中的每一列中,填充數據到新創建的「訪問」 POJO
      • 使用訪問POJO,構建用於Sybase的查詢
      • 查詢的Sybase:
      • 如果結果集爲空,在Sybase
      • 插入一條記錄
      • 如果結果集不爲空,實例化另一個POJO和東西Sybase數據進去。
      • 比較兩個POJO:
      • 如果POJO匹配:不執行任何操作,請轉到下一行。
      • 如果POJO的不匹配:使用從訪問POJO

現在的規定,這是目前完成工作的數據在一個非常執行更新到Sybase,儘管程序,單線程方式,其中有我的問題:以多線程的方式來區分兩個數據庫(這恰好是不相關的)的正確方法是什麼

我有一些多線程的經驗,但我不確定正確的方法,因爲我從來沒有排隊插入/更新。這就是說,我並不完全確定排隊是正確的方法 - 那麼批量更新/插入是如何呢?

在這方面有一些經驗的人會提供一些關於如何解決這個問題的高層次的見解?就目前來看,我在大約2個小時內攪動了1.5m行,大約200 TPS。非常慢。任何指導將不勝感激,如果有必要,我會很樂意提供更多信息。

+1

另請參閱http://stackoverflow.com/a/29502316/32453 – rogerdpack

回答

1

根據我的經驗,有一款能夠正確完成這種工作的工具非常有價值。它可能會很慢,但如果速度夠快,改變它以使其更快就不值得冒錯的結果。儘管如此,每個表的當前差異程序本身也適用於多線程。與可能需要更新的(Sybase)數據庫進行通信時,該過程可能會在網絡延遲時間內損失大部分時間。擁有一對線程並行處理將有助於提高吞吐量。

讓一個線程從輸入(MS Access)數據庫中讀取表中的記錄,並將Access Pojos放入併發隊列中(例如ConcurrentLinkedQueue)。讓多個線程從這個隊列中讀取Access Pojos並且並行執行更新過程。
當表中沒有更多記錄時,讓讀線程在隊列中放置特殊的「表末尾」Access Pojos,以便更新線程知道何時停止。另外,當隊列變得太大時,讀線程需要暫停(或使用ArrayBlockingQueue)。
重複下一個表格。

這裏的想法是,當前的源代碼被移動而不會被太多改變(這最大限度地減少了破壞東西的風險):讀取線程獲得一個Runnable對象,包含當前代碼以從MS Access數據庫中讀取並創建一個訪問Pojo(並在循環中執行此操作),寫入線程將獲得一個帶有當前代碼的Runnable,用於比較和更新Sybase數據庫。

+0

這很有道理;我熟悉將期貨提交給需要ArrayBlockingQueue的ThreadPoolExecutor,但尚未有機會實施(或調查)ConcurrentLinkedQueue,所以我會檢查一下。我非常感謝答覆;這整個時間似乎都在盯着我。 – lux

+1

現在你已經提到它了:'Queue + Write thread = FixedThreadPool',你不需要自己做這個。只需讓read-thread將Access對象封裝在一個可運行的對象中,並且您只需要一個'Executors.newFixedThreadPool(int)'。 – vanOekel