異常日誌mysql
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transactionsql
### The error may involve defaultParameterMapapp
### The error occurred while setting parametersspa
### SQL: UPDATE t_withdraw_apply SET last_apply_time=? WHERE user_id = ? AND state = 0rest
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction日誌
; SQL []; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction事務
很顯然,出現死鎖的SQL語句是UPDATE t_withdraw_apply SET last_apply_time=? WHERE user_id = ? AND state = 0get
再看業務邏輯it
int i = withdrawApplyDAO.add(apply);io
if(i == 1) {
//獲取該用戶最先的待提現申請時間
Timestamp earlierTime = withdrawApplyDAO.getEarlierApplyTime(userId);
withdrawApplyDAO.updateEarlierApplyTime(userId,earlierTime);//更新冗餘字段
//扣除帳戶餘額,而後寫入gold_log日誌
int j = userDAO.updateUserGold(0-amount, userId);
......
那麼爲何會出現死鎖呢?
原來是這樣的,用戶點擊過快同時提交了兩次提現申請
那麼就會開啓兩個事務
事務1 插入一條apply
事務2 也插入一條apply
事務1 執行更新 updateEarlierApplyTime ,因爲事務2插入的數據也須要更新,因此這個時候 事務1須要等待事務2提交後才能執行
事務2 頁執行更新 updateEarlierApplyTime ,一樣須要更新事務1插入的輸入,也須要等地事務1完成才能繼續執行,這樣就出現了死鎖
怎麼解決這個問題呢?
首先出現這個問題的緣由是事務1更新的數據包含了事務2插入的數據,事務2更新也包含了事務1插入的數據,那麼咱們能夠讓代碼改成
withdrawApplyDAO.updateEarlierApplyTime(userId,earlierTime);//更新冗餘字段
withdrawApplyDAO.add(apply);
這樣就能解決死鎖問題
其次,出現這樣的問題是用戶重複提交致使的,因此應該作重複提交的限制,