【博客園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