互聯網應用業務需求迭代更新速度快,業務層代碼常常性變更,致使代碼質量變差,另外應用版本發佈週期也短,所以除了完整的測試體系以外,在後端架構業務邏輯層中,容錯設計對魯棒性和問題的快速修復都相當重要。B/S應用也好,C/S應用也好,處理好這個問題高可用及快速發佈都有保證。
業務邏輯層實現較多使用的高級語言例如Java,Python,PHP,ECMAScript系列,都會在發生錯誤的時候拋出各類異常,而後程序就會在出錯點終止,一般能夠經過這些語言提供的異常捕獲機制處理出錯,確保進程繼續運行,接受新的業務調用請求,C/C++在這個問題上有點悲劇。
在一個業務調用執行過程當中,一段順序執行的邏輯代碼,通常來講各行均可能存在着對全局數據的操做,例如數據庫寫操做,或者進程內全局變量更新操做,若是這段代碼執行到一半出錯而拋出異常終止(常常可能發生的事),但因爲業務進程容錯,進程會繼續運行不會受到影響,只是這段代碼原來設計改變的數據可能只修改了部分,另外出錯點後面的數據沒有修改到,因而產生了業務數據完整性的問題,這不是關係型數據庫的數據引用完整性問題,你無法徹底經過設計良好的完整引用來排除,所以這種問題是常常存在的。
一般來講,對於這種問題,咱們能夠這樣解決,經過對邏輯代碼修復,同時分析對生產數據的影響,而後同步進行修復;另一種方法是在該段代碼開始執行時就啓用數據庫事務,出錯時直接rollback,若是你使用的是關係型數據庫的話,比較大殺器。
分析這兩種方法,第一種方法來講加劇了修復的工做量和時間,要求也比較高,另外取決於應用的設計,對一個線上應用來講該問題也可能已經照成了難以預料的連帶錯誤;第二種辦法解決得比較完全,可是啓用事務會大大影響數據庫服務器的併發效率,另外目前流行的NoSQL數據庫對事務的支持比較糟糕。
那麼如何更好的解決容錯設計下的數據完整性這種問題呢?
個人想法是能夠參照關係型數據庫的事務機制在業務邏輯層實現本身的寫調用延遲,分離邏輯代碼和數據寫調用(數據讀調用無需關心)。
這樣的架構下,業務代碼出錯不會影響到全局數據,執行成功則最後將寫調用提交執行,若是執行失敗則能夠刪除寫調用記錄,至關於事務rollback,該業務的調用對外部來講跟沒發生過同樣;經過適當的封裝,在編寫業務代碼時也無太大的區別,不會帶來代碼上的習慣轉變問題。
該實現帶來的好處是調用拋出異常終止時無需再關心數據完整性的修復問題,只須要修復相應的業務代碼便可,固然這只是針對本地的調用,對於存在於本地業務邏輯中的RPC則顯式兩階段提交是不可避免的,不在考慮範圍。
我已經在本身的服務端架構中實現了該想法。將繼續測試。數據庫