事務 鎖 悲觀鎖 樂觀鎖 概念 應用場景 使用方式 小記
【部落格園cnblogs筆者m-yb原創(部分引用, 在文末有註明),轉載請加本文部落格連結,筆者github: https://github.com/mayangbo666,公眾號aandb7,QQ群927113708】
https://www.cnblogs.com/m-yb/p/9974979.html
最近寫程式碼時, 發現自己對事務和資料庫的鎖的使用有點不明白, 而這些是面試易考點, 查了些資料, 對這些進行重新梳理表述如下:
所謂事務是使用者定義的一個數據庫操作系列,這些操作要麼全部執行,要麼全部不執行,是一個不可分割的工作單位。例如在關係資料庫中,一個事務可以是一條sql語句、一組sql語句或整個程式。
【事務】:對加了事務的一系列操作, 會在執行的時候 -> 同時成功, 同時失敗. spring中使用事務, 可在方法頭上加這樣一行註解程式碼:
@Transactional(rollbackFor = Exception.class)
為什麼有了事務這東西,還需要樂觀鎖悲觀鎖?事務是粗粒度的概念、樂觀鎖悲觀鎖可以更細粒度的控制;
比如搶票,假設餘票只有1張;隔離級別可以保證事務A和事務B不能讀到對方的資料,也不能更新對方正在更新的資料,但是事務A和事務B都認為還有1張餘票,於是出票,並更新為0;
事務解決了併發問題,已經不存在併發問題了;
但是事務B讀取的是過時資料,依據過時資料做了業務處理;
所以需要樂觀鎖或者悲觀鎖,來記錄一個資訊:當前已經讀取的資料,是不是已經過時了!
事務有這麼幾種實現方式:鎖協議、MVCC、時間戳排序協議、有效性檢查協議,鎖協議是事務的一種實現方式,事務 = 用鎖封裝的一個函式,可以重用而已,但是這幾個事務的函式覆蓋面太粗粒度了,所以有時候我們還得藉助於鎖來進行細粒度控制;
事務不能保證每個操作結果正確,售票時超賣還是會發生。
事務保證整個操作的成一個組,要麼全做要麼全不做, 但是不能保證多個事務同時讀取同一個資料
資料物件被加上排它鎖時,其他的事務不能對它讀取和修改;加了共享鎖的資料物件可以被其他事務讀取,但不能修改
事務可以用鎖實現,可以保證一致性和隔離性,但是鎖用來保證併發性;
隔離性和併發性有點類似,但是隔離性只是保證不會出現相互讀取中間資料,卻無法解決併發的問題.
當業務要求執行這組操作的成功率時, 使用悲觀鎖;
當業務要求迅速返回狀態的速度時, 使用樂觀鎖;
悲觀鎖(排他鎖)、樂觀鎖(共享鎖)在資料庫的使用:
悲觀鎖在sql語句的最後加上 for update
樂觀鎖可通過版本控制, 在sql語句的更新操作語句中加入 version = #{oldVersion}條件
注本文部分轉載自:
作者:chinoukin
來源:CSDN
原文:https://blog.csdn.net/chinoukin/article/details/79005596