1. 程式人生 > 資料庫 >MYSQL事務和鎖

MYSQL事務和鎖


2020年11月12日17:20:52 MYSQL事務 王凱玉


目錄

事務的定義

事務是資料庫管理系統執行過程中的一個邏輯單位,由一個有限的資料庫操作序列構成


儲存引擎

預設的innodb可以滿足大部分併發讀寫 、NDB適用於叢集 這兩個都支援事務


事務的四大特性

最終都是為了保證一致性

  • 原子性 - 事務不可分割,是一個邏輯單位
  • 一致性 - 資料庫的自身完整性的約束,不能被破壞,在使用者的程式碼中控制
  • 隔離性 - 有很多事務去同時操作一張表,這種併發操作應該是互不干擾的
  • 永續性 - 對資料庫進行增刪改的操作時,只要事務提交成功,結果應該是永久性的,不管資料庫是崩潰了還是重啟了,資料都不會恢復到之前的狀態

資料庫什麼時候會出現事務?

執行一個增刪改的語句的時候 自動開啟事務

  • start transaction 手動開啟事務

  • begin 手動開啟事務

  • commit 提交

回滾提交都可以結束事務,在圖形化介面裡 斷開連線 會自動回滾

事務可以去鎖定一行資料,在結束事務的時候會釋放鎖


事務併發會帶來什麼問題?

  • 髒讀(READ UNCOMMITTED)

    一個事務讀取到了其他事務還沒有提交的資料,造成前後兩次讀取的結果不一致

    (沒有提交的資料在記憶體的緩衝池中 不會寫入到磁碟中)

  • 不可重複讀(READ COMMITTED)

    一個事務讀取到了其他事務已提交的資料,造成前後兩次讀取結果不一致

  • 幻讀(REPEATABLE READ)

    新增資料 造成事務的兩次讀取結果不一致

總結: 事務併發的三大問題,都是資料庫讀一致性的問題

​ 必須由資料庫提供一定的事務隔離機制來解決。


事務的四種隔離級別(SQL92標準)

  • 未提交讀(Read Uncommitted):一個事務可以讀取到其他事務未提交的資料,會出現髒讀 這最低的事務隔離級別

  • 已提交讀(Read Committed):解決髒讀,但是不能解決不可重複讀的問題

  • 可重複讀(Repetable Read):解決髒讀和不可重複讀,不能解決幻讀

  • 序列化(Serializable):解決事務併發的所有問題,事務一個個排隊執行 沒有了併發

    副作用:執行速度慢(操作一張資料表的時候 其他事務不能做操作,併發效率降低,生產環境中不會使用)

MYSQL比較貼近這個標準,事務隔離級別越高,支援的併發度就越低。

”可重複讀“:在innodb中 已經解決了所有問題

Q:想要保證一個事務中前後兩次讀取資料結果一致?

A:- 在讀取資料之前,加鎖,組織其他事務對資料進行修改

​ - 生成一個數據請求時間點的一致性資料快照,用這個快照提供一定級別的一致性讀取


MYSQL中的鎖

從鎖的粒度劃分:行鎖、表鎖

從鎖的用法劃分:樂觀鎖、悲觀鎖

從鎖的型別劃分:

  • 排他鎖:又叫寫鎖,不能和其他鎖並存,一個事務獲取了一個數據行的排他鎖,其他事物就不能再獲取這個鎖,只有獲取了排他鎖的事務才能操作資料

    # 加鎖
    - 自動:delete/update/insert # 預設上鎖
    - 手動:select * from student where id = 1 FOR UPDATE;
    
  • 共享鎖:又叫讀鎖,多個事務都可以共享這把鎖,都能訪問到資料,但是隻讀不能修改。

    # 加鎖
    slect * from student where id = 1 LOCK IN SHARE MODE;
    
    # 釋放 (釋放共享鎖就是事務的結束)
    commit/rollback ;
    

    鎖的作用:競爭資源