聊聊MySQL事務

2022-04-12 20:27:03 字數 1855 閱讀 6546

事務特性: acid(atomicity、consistency、isolation、durability,即原子性、一致性、隔離性、永續性)

隔離性與隔離級別

隔離級別:多個事務同時執行時,可能出現髒讀、不可重複讀、幻讀,隔離級別是為了解決這些問題。

隔離越嚴實,效率越低,所以需要平衡。

事務隔離級別包括:

讀未提交:乙個事務還沒提交時,它做的變更就能被別的事務看到。

讀提交:乙個事務提交之後,它做的變更才會被其他事務看到。

可重複讀:乙個事務執行過程中看到的資料,總是跟這個事務在啟動時看到的資料一致(可重複讀隔離級別下,未提交變更對其他事務也是不可見的)

序列化:對於同一行記錄,「寫」會加「寫鎖」,「讀」會加「讀鎖」。當出現讀寫鎖衝突時,後訪問的事務必須等前乙個事務執行完成,才能繼續執行。

舉個簡單例子說明:

實現上,資料庫裡面會建立乙個檢視,訪問的時候以檢視的邏輯結果為準。

「可重複讀」事務隔離的實現(mysql預設隔離級別)

mysql 中,實際上每條記錄在更新的時候都會同時記錄一條回滾操作。記錄上的最新值,通過回滾操作,都可以得到前乙個狀態的值。

假設乙個值從 1 被按順序改成了 2、3、4,在回滾日誌裡面就會有類似下面的記錄。

當前值是 4,但是在查詢這條記錄的時候,不同時刻啟動的事務會有不同的 read-view。

如圖中看到的,在檢視 a、b、c 裡面,這乙個記錄的值分別是 1、2、4,同一條記錄在系統中可以存在多個版本,就是資料庫的多版本併發控制(mvcc)。

即使現在有另外乙個事務正在將 4 改成 5,這個事務跟 read-view a、b、c 對應的事務是不會衝突的。

回滾日誌不能一直保留,什麼時候刪除呢?答案是,在不需要的時候才刪除。

系統會判斷,當沒有事務再需要用到這些回滾日誌時,回滾日誌會被刪除。

什麼時候不需要呢?當系統裡沒有比這個回滾日誌更早的 read-view 的時候。

所以建議盡量不要使用長事務:

1.長事務意味著系統裡面會存在很老的事務檢視。這個事務提交之前,資料庫裡面它可能用到的回滾記錄都必須保留,會導致占用大量儲存空間。

2.mysql 5.5 及以前的版本,回滾日誌是跟資料字典一起放在 ibdata 檔案裡的,即使長事務最終提交,回滾段被清理,檔案也不會變小。

3.長事務還占用鎖資源,也可能拖垮整個庫

事務的啟動方式

建議使用set autocommit=1 和顯示啟動事務語句, 如begin 或 start transaction。(有些框架會預設set autocommit=0,這可能導致長事務)

如果介意begin多互動一次,可以使用commit work and chain。這樣會在提交的時候自動啟動下乙個事務。

可以在 information_schema 庫的 innodb_trx 這個表中查詢長事務,比如下面這個語句,用於查詢持續時間超過 60s 的事務。

select

*from information_schema.innodb_trx where time_to_sec(timediff(now(),trx_started))>

60

聊聊MySQL事務的特性和隔離級別

網上對於此類的文章已經十分飽和了,那還寫的原因很簡單 作為自己的理解筆記。前言此篇文章作為自己學習mysql的一些個人理解,使用的引擎是innodb。首先先講講事務的概念,在 高效能mysql 第三版中其對事務的描述是這樣的 事務就是一組原子性的sql查詢,或者說乙個獨立的工作單元。如果資料庫引擎能...

聊聊分布式事務

事務就是乙個會話過程中,對上下文的影響是一致的,要麼所有的更改都做了,要麼所有的更變都撤銷掉。就要麼生,要麼死。沒有半死不死的中間不可預期狀態。參考下薛丁格的貓。事務是為了保障業務資料的完整性和準確性的。分布式事務,常見的兩個處理辦法就是兩段式提交和補償。兩段式提交典型的就是xa,有個事務協調器,告...

今天來聊聊事務傳播行為

俺是個粗人,那麼俺就用最白話的語言來說說俺心目中的事務傳播行為。事務這個我在此部落格的其他帖子中也有專門說過 通俗的理解就是,乙個需要做多件事的乙個任務。事務是具有原子性,同乙個事務中,所有的事情要麼都沒做,要麼都做完了。這樣說就應該理解了事務,那麼事務的傳播行為就可以很好理解了。用具體的業務場景,...