支付業務很大程度上依賴於數據庫做支持,正確的設置數據庫參數以及正確的使用數據庫對非常重要,我這把
自己之前的一些心得貼出來,拋磚引玉,大家可以把自己的一些心得分享出來供大家參考學習。
一.數據庫配置
1. innodb_flush_log_at_trx_commit,這個對支付業務來說是關鍵性的設置之一,可選的參數值有0,1,2, 支付需要設置成1.
2. 對交易以及記賬部分來說,必須是innode引擎,以支持事務
3. 事務隔離級別,權衡安全性和效率,使用可重複讀
4. innodb_lock_wait_timeout,這個是鎖超時時間,不建議太大,怕引起雪崩
二.業務設計
1. 不用物理刪除,即儘量避免用delete語句,drop命令等;通過軟刪除處理,即通過額外的字段標
2. 明記錄的刪除狀態;雖然對寫代碼來講有些麻煩,但實踐證明是非常值得的
3. 在系統設計之初就要定好編碼規範,對存入的數據做相應轉換並做好escape處理
4. 除列表查詢外,儘量用主鍵操作;核心交易系統中儘量避免非主鍵操作
5. 避免schema中1對多設計,概念簡單,編碼很難
6. 就mysql來說,儘量使用其最簡單的功能,不用其高級功能如觸發器,連表等
7. 就mysql來說,儘量不讓其做計算功能,而是讓業務層來實現計算邏輯
8. 當要鎖多條記錄時, 要考慮死鎖的可能以及預防的措施
9. 按業務垂直劃分原則,儘量把不同的業務方不同的庫中
10. 堅持小事務,一個大事務與將其拆分成的十個小事務相比,小事務對數據庫壓力更小;另外,事務
中做盡可能少的事情,神馬參數校驗之類的事情能拉出去就拉出去
11. 數據庫連接長時間不用超時斷開是常見的,應用中需要考慮
12. 對超大型系統來說,分佈式事務是有價值的;但在大多下情況下,單機事務能很好的滿足需要
13. 主從延遲總是會有的,有時候會很大,設計中要考慮
14. 讀寫賬號分開,讀賬號select權限即可,寫賬號update,insert即可
15. where條件key='value'的模式中,加上單引號總是對的,不加在某些情況下有很多令人意外的副
作用
16. 儘量使用簡單的數據類型,char系列,int系列以及date系列即可
17. 事務的使用上,在線交易使用悲觀鎖
18. 事務框架的選擇上,使用控制力度比較大的,直接TransactionManager,不推薦使用聲明式事務
19. 採用InnoDB引擎,UTF8編碼
20. 有狀態字段的記錄,狀態的取值不宜太多, 6 ~ 7個應該是上限了, 最好不要超過 4個
21. 每個表都應該有自己的主鍵,且儘量讓表內主鍵保持遞增
22. 不使用自增主鍵
23. 在線查詢的字段一定要建立覆蓋索引
24. 分頁查找一定不能直接limit m,n,一定要做優化
三. 應用規範
1. 當進行賬戶餘額變化操作時,總是校驗賬戶是否被凍
2. 對單據如Trade,Charge進行處理,併發總是要考慮的,需要鎖記錄後進行校驗;從數據庫查詢的
時候,請先起動事務,並用select...for update;防止併發帶來的問題;從性能上將,鎖交易單本身不
會成爲性能瓶頸
3. 更新賬戶餘額之前必須加鎖,即起事務+select...for update; 更新餘額的語句建議是update table
set 餘額=餘額+/-發生額, 自然在代碼邏輯中做各種邊界值校驗,包括不溢出,不小於0等
4.金額都統一單位,以分爲單位合適;數據類型爲有符號64位整形數合適
5. 對金額計算時,對溢出的預防總是需要的
6.使用select時,慎用*,儘量明確的枚舉出字段名
7.與外部交互的地方,記錄下外部發生時間
8. db命名採用"cashpay"前綴
9. 表命名採用"t_"前綴
10. 字段命名採用"F_"前綴
11. 每個表都會有一個字段記錄上次更新時間
12. 在一個session中的所有數據庫更新記錄,上次更新時間都是一致的
最後附上筆者創建的一個java技術交流羣,歡迎大家進羣交流java相關的技術,羣主會不定時發紅包,組織抽獎,獎品是下面幾本書之一:
從paxos到zookeeper分佈式一致性原理與實踐 作者:倪超
Redis設計與實現 作者:黃建宏
kafka源碼分析
分佈式系統架構設計與實現
高性能mysql
Innodb引擎原理分析
還有幾本,篇幅限制就不一一列舉了