細談Mysql事務

逆月翎發表於2019-10-23

文章原創於公眾號:程式猿周先森。本平臺不定時更新,喜歡我的文章,歡迎關注我的微信公眾號。

file

上一篇著重談到了MySQL鎖的概念,裡面談到了事務的概念,其實大部分開發者對於事務肯定不陌生,事務的概念其實就是一組SQL語句組成一個執行單元,如果單元中的某個SQL語句執行出現異常,則需要將整個事務進行回滾到未修改的狀態。只有單元中全部SQL語句都成功執行,才會提交資料代表事務執行成功。而Mysql其實前幾篇我們都已經知道是支援多種儲存引擎的,其實正是因為MyISAM引擎不支援事務被InnoDB取代的原因。所以本篇文章主要是針對InnoDB引擎詳細瞭解下事務這個概念。

事務特性

  • 原子性: 事務是一個原子操作單元,其對資料的修改,要麼全都執行,要麼全都不執行。
  • 一致性:事務中包含的處理要滿足資料庫提前設定的約束,如主鍵約束或者NOT NULL 約束等。
  • 隔離性:事務處理過程中的中間狀態對外部是不可見的。
  • 永續性:事務完成之後,它對於資料的修改是永久性的。

隔離性的四種隔離級別

InnoDB引擎支援的4種事務隔離級別分別是:讀未提交、讀已提交、可重複讀、序列讀。

  • 讀未提交:允許髒讀,可以讀取其他session中未提交的髒資料。
  • 讀已提交:不可讀取其他session尚未提交的資料,只有其他session資料已提交才能讀取到,為不重複讀。
  • 可重複讀:該級別下可重複讀,InnoDB引擎預設採用可重複讀,不允許讀取還未提交的髒資料,但是可能存在InnoDB獨有的幻讀。
  • 序列讀:該級別下隔離程度最高,事務只能一個接著一個序列執行,無法併發執行。每次序列讀都需要獲得表級共享鎖,讀寫操作都會阻塞。

幻讀

事務在插入一條已經經過檢查不存在的記錄,但是插入結果是資料已經存在,之前的檢查操作如同幻影。Mysql預設採用可重複讀級別,所以只可能出現幻讀的情況。

設定事務隔離級別

可以在my.ini檔案中[mysqld]下配置transaction-isolation屬性,隔離性的四個值為:READ-UNCOMMITTED、READ-COMMITIED、REPEATABLE-READ、SERIALIZABLE,分別對應讀未提交、讀已提交、可重複讀、序列讀四種隔離級別。

事務分類

事務一般分為兩種:隱式事務和顯示事務。在Mysql中,事務預設是自動提交的,所以說每個DML語句實際上就是一次事務的過程。隱式事務:沒有開啟和結束的標誌,預設執行完SQL語句就自動提交,比如我們經常使用的INSERT、UPDATE、DELETE語句就屬於隱式事務。顯示事務:需要顯示的開啟關閉,然後執行一系列操作,最後如果全部操作都成功執行,則提交事務釋放連線,如果操作有異常,則回滾事務中的所有操作。

事務使用步驟開啟事務:關閉自動提交,然後開啟事務。事務操作:一系列DML語句執行。事務結束:根據事務操作成功與否選擇提交事務或者回滾事務操作。

接下來我們簡單的使用事務實現使用者A向使用者B轉賬的操作:

建立使用者表並插入兩條使用者資料:

file

配置資料庫連線資訊:

file

接下來從連線池中取出一個資料庫連線並進行資料庫連線:

file

資料庫連線成功,則使用connection物件開啟事務:file

然後查詢轉賬賬號與待轉賬賬號是否存在,並進行轉賬等一系列操作,這裡由於魔鬼回撥的原因我這裡使用async庫變成鏈式呼叫:

file

最後根據事務操作的成功或失敗進行事務提交或者事務回滾,並且釋放資料庫連線:

file

然後可以測試轉賬成功的情況可以發現轉賬操作成功了

file

再次測試轉賬失敗的操作可以發現扣除A積分和增加B積分的操作全部被回滾了,所以A和B的積分餘額都沒有發生改變

file歡迎關注公眾號:程式猿周先森。文章原創於微信公眾號,本平臺不定時更新。

相關文章