在做erp訂單接入倉庫庫存的時候出現了乙個問題。下單會讀取該商品是否有庫存。如果有那麼就下單 減去(可下單庫存,物理庫存不變) 沒有則提示庫存不足
在併發情況下就會導致 u1使用者下單編號為1的商品1個 u2使用者也下單編號為1的商品1個。編號為1的商品庫存只有1個。 那麼當u1在讀取出資料的時候發現庫存有乙個 但是還沒有寫入庫存的操作 u2也下單成功並提交 那麼就會導致資料錯亂 本來應該是只有u1會下單成功u2則提示庫存不足
這裡可以用事物的隔離機制或樂觀鎖來解決
事物是乙個邏輯單元
原子性:事物裡面是一塊邏輯單元 要麼都執行 要麼都不執行
一致性:事物處理前與處理後的狀態的要是一致的(a賬戶有200元 b賬戶有300元 共計500元 a賬戶給b賬戶轉賬100元。事物處理後2個賬戶總額也為500元)
隔離性:每個事物都有自己的資料空間,使事物的處理結果不會被別的事物所影響
永續性:事物提交 資料就永久的儲存下來了
事物的隔離級別
read uncommitted 讀取未提交的
這個隔離級別可能會導致髒讀。它可以讀取別的事物更改後並未提交的資料。比如以倉庫庫存判斷為例子 在乙個事物裡面讀取商品 並修改商品庫存為0但是事物還沒有提交 另外乙個事物下單 發現沒有庫存 提示庫存不足 這個時候第乙個事物取消 導致髒讀
read committed 讀取已經提交的
這個隔離級別能夠避免髒讀。因為只能讀取事物已經提交的資料。但是會出現不可重複讀
例子:乙個使用者下單乙個a產品。開啟乙個事物 1.讀取產品庫存 2.執行邏輯操作 3.這個時候另外乙個事物修改了這個產品的庫存。 3.真正下單再去讀取庫存 發現數量跟上一次讀取的不一致(因為雖然隔離級別只能讀取已提交 但是別的事物能夠修改 會導致不可重複讀)
repeatable read 可重複讀
這個事物隔離級別可以解決上面的那種情況 當乙個事物在處理某條資料的時候 別的事物既不能讀取也不能修改 但是會造成幻讀 因為不能修改和讀取未提交的資料 但是可以插入和刪除資料 比如個人賬戶消費為例子 乙個事物查詢用a當月消費記錄總和來做信用評分 select sum(money) from table 讀取出來當月消費2000元 。當事物還沒有提交 使用者a老婆這個時候在美容院消費5000 那麼table表新增一條消費記錄為5000的資料 這個時候出現幻影讀(事物讀取資料與實際資料不符)
serializable 序列化
這個隔離級別最高 能夠避免 髒讀 不可重複讀 幻影讀 但是效率低(既乙個事物在操作某條資料的時候 別的事物不能讀取和修改這條資料 也不能往表裡插入資料)
根據不同的併發場景選擇不同的事物隔離機制
樂觀鎖即使用資料在解決併發情況下資料不一致的情況
以倉庫庫存為例
在倉庫表增加乙個最後修改時間字段 並將它作為條件
倉庫庫存表擁有a產品 可下單庫存1個
u1使用者下單a產品 讀取出來判斷庫存是否充足 充足的話 在事物裡面下單並更新可用庫存 update stok set num-=1,lastupdatedatetime=datetime.now where id=a and lastupdatedatetime=上一次的修改時間
就算在u1提交之前別的事物比他先提交 那麼u1 提交的時候 lastupdate被別的事物更新了 則條件不成立提交失敗(受影響行數為0 回滾下單操作)
注:oracle 只支援serializable read committed
資料庫事務隔離級別
資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...
資料庫事務隔離級別
資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...
資料庫事務隔離級別
資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable 這四個級別可以逐個解決髒讀 不可重複讀 幻讀 這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted re...