在php與數據庫的交互中,若是併發量大,而且都去進行數據庫的修改的話,就有一個問題須要注意.數據的鎖問題.就會牽扯數據庫的事務跟隔離機制
數據庫事務依照不一樣的事務隔離級別來保證事務的ACID特性,也就是說事務不是一開啓就能解決全部併發問題。一般狀況下,這裏的併發操做可能帶來四種問題:php
- 更新丟失:一個事務的更新覆蓋了另外一個事務的更新,這裏出現的就是丟失更新的問題。
- 髒讀:一個事務讀取了另外一個事務未提交的數據。
- 不可重複讀:一個事務兩次讀取同一個數據,兩次讀取的數據不一致。
- 幻象讀:一個事務兩次讀取一個範圍的記錄,兩次讀取的記錄數不一致。
一般數據庫有四種不一樣的事務隔離級別:mysql
大多數數據庫的默認的事務隔離級別是提交讀(Read committed),而MySQL的事務隔離級別是重複讀(Repeatable read)。對於丟失更新,只有在序列化(Serializable)級別纔可獲得完全解決。不過對於高性能系統而言,使用序列化級別的事務隔離,可能引發死鎖或者性能的急劇降低。所以使用悲觀鎖和樂觀鎖十分必要。 併發系統中,悲觀鎖(Pessimistic Locking)和樂觀鎖(Optimistic Locking)是兩種經常使用的鎖:laravel
- 悲觀鎖認爲,別人訪問正在改變的數據的機率是很高的,所以從數據開始更改時就將數據鎖住,直到更改完成才釋放。悲觀鎖一般由數據庫實現(使用SELECT...FOR UPDATE語句)。
- 樂觀鎖認爲,別人訪問正在改變的數據的機率是很低的,所以直到修改完成準備提交所作的的修改到數據庫的時候纔會將數據鎖住,完成更改後釋放
***
以mysql爲例子:
myisam存儲引擎使用表縮
innodb使用行鎖(明確指定了主鍵的狀況下,不然也是表鎖)與表鎖
通常的作法是:
1 開啓事務
2 進行數據更改
3 回滾或者提交
在具體的業務邏輯中,因爲隔離機制的不一樣,致使結果的不一樣.
樂觀鎖與悲觀鎖使用的也比較多.面試
因爲悲觀鎖在開始讀取時即開始鎖定,所以在併發訪問較大的狀況下性能會變差。對MySQL Inodb來講,經過指定明確主鍵方式查找數據會單行鎖定,而查詢範圍操做或者非主鍵操做將會鎖表。sql
以上內容但願幫助到你們, 不少PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那裏入手去提高,對此我整理了一些資料,包括但不限於:分佈式架構、高可擴展、高性能、高併發、服務器性能調優、TP6,laravel,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨須要的能夠免費分享給你們 ,須要戳這裏 PHP進階架構師>>>實戰視頻、大廠面試文檔免費獲取 shell