分析ERP审单失败,提示:库存不足的原因及应对方案
第一步:創建測試表 test,如下:
CREATE TABLE `test` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',`now` datetime DEFAULT NULL COMMENT '時間',`year_month` binary(7) DEFAULT '\0\0\0\0\0\0\0',`stock` mediumint(11) unsigned NOT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8模擬前提條件:
MySQL版本:5.7.26
事務級別:REPEATABLE-READ
第二步:模擬用戶A制單、審核
START TRANSACTION; select `stock`,`now` from test where id = 1 lock in share mode; UPDATE test SET `stock` = `stock`-50,`now`=NOW() where id = 1; COMMIT;第三步:模擬用戶B制單、審核
START TRANSACTION; SELECT `stock`,`now` from test where id = 1 lock in share mode; UPDATE test SET `stock`=`stock` - 60,`now`=NOW() WHERE id = 1; COMMIT;審單失敗的原因分析
1.以測試的MySQL版本為例,事務的默認超時為:120秒,實際測試過程種發現,若采用默認的120秒超時機制,用戶B的事務在用戶A的鎖超時后,會得以執行成功,通常用戶B的事務被阻塞90秒左右,此時用戶A的鎖已經過期解除,因此用戶B的事務可以正常執行,也就是說:用戶A先執行扣減庫存-50,但是因為某種原因沒有commit,此時用戶B也執行扣減庫存,因為此時處于加鎖狀態,用戶B的事務扣減庫存會被阻塞,這個阻塞大概會持續90秒左右(這個阻塞時長依據實際情況會略有不同),用戶A的鎖過期被解除,這個時候用戶B的事務得以正常執行成功并commit,此時實際庫存是:stock - 60,即:100 - 60 = 40
###用戶A經過長時間的擱置,已經制單,但是沒有及時審核單據,過了很久,比如:遲疑超過了事務wait_timeout的半天,更甚者,第二天才來審核這個單據
2.用戶A點擊審單操作,這張單據是在用戶B制單之前產生的,用戶A要審核的單據內容是:stock - 50,即:100 - 50 = 50,然而實際情況是:用戶B已經扣減庫存-60,當前實際庫存stock = 40,在執行用戶A的第二步審核單據時,系統取得實際stock = 40,40 - 50 = -10,執行 update 失敗,接著界面會提示庫存不足
應對方案:
1.設置合理的事務超時:SET innodb_lock_wait_timeout=30; -- 默認的是 31536000秒
建議設置在 30 - 60 之間比較合理,假設超時為:30秒,那么用戶B扣減庫存時阻塞30秒,此時用戶A加鎖還在有效期內,用戶B
2.提示信息優化:不要簡單的提示 庫存不足,這樣用戶會產生疑惑,以用戶A為例:當他看到提示庫存不足,他會想:這張單制單內容顯示:庫存100,扣減庫存50,庫存結余50,庫存是足夠扣減的,為什么會提示庫存不足?
建議優化措施:庫存不足時要提示出庫存不足的原因,比如:庫存不足,當前庫存:40,待扣減50,最好還可以帶出關聯單據的查詢,可以很直觀的看出問題出在了哪里
總結
以上是生活随笔為你收集整理的分析ERP审单失败,提示:库存不足的原因及应对方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ThinkSNS安装指南说明
- 下一篇: Java创建学生喂养动物类