並發入庫面臨重復數據的問題
阿新 • • 發佈:2018-02-28
方案 ice 服務 數據庫 關註 處理 user 進行 數據 ),發現username不存在,那麽就會導致user表中插入了兩個username一樣的數據(步驟2)。
並發入庫面臨重復數據的問題
以User類為例,當添加一個用戶時,首先會去判斷用戶是否已經存在(即username是否已經在數據庫中了),如果沒有,則insert一條用戶數據,如果有,則提示用戶名已存在。
將這個操作看作函數:UserService.saveUser(User user),有3個步驟:
private int saveUser(User user) {
if (1.username不存在) { // 2.入庫; } else { // 3.提示用戶名已存在; }
}
這個saveUser函數實際上是線程不安全的,假設兩個線程A和線程B,兩個線程同時進行了判斷(步驟1
解決方案一
最直接的,通過添加synchronized關鍵字,將方法變成同步方法。
優點:簡單直接
缺點:性能問題;後期的維護成本較高;最終要的,當服務部署在多臺設備時不起作用
解決方案二
在數據庫的user表中,將username字段設為唯一索引,這樣當插入重復數據時,數據庫會拋出異常,無法入庫,可以通過異常處理的方式來處理
優點:從比較根源的數據庫層面解決了問題,適用與分布式環境
缺點:需要關註異常處理
並發入庫面臨重復數據的問題