MySQL基礎(十四):事務

  • 本博客是《MySQL基礎》系列博客的第十四部分,簡單介紹MySQL中的事務處理,包括事務的概念、特徵以及事務併發所帶來的問題及事務隔離級別
  • 本博客既爲方便自己查看複習而作,亦爲你而作,望能有所裨益
  • 學習交流請聯繫 [email protected]

基本概念


想必大家雙十一的時候都曾瘋狂地剁過手,過年的時候都曾激昂地搶過火車票,如果你曾細心留意,你會發現每年這個時候一些科技媒體都會報道這些數據庫是如何如何處理這些高併發事務的,也就是說所謂的事務反映出來不過是數據的變動。你提交一份訂單,購買一張火車票,它背後的數據庫都會提交相應的事務,以保證系統數據的準確性等。


事務是一些列DML語句的集合,即衆多插入、更新、刪除語句組成的一個程序執行單元

四大特徵

  • 原子性(Atomicity):事務是一個最小的工作單元,整個工作單元要麼一起提交成功,要麼一起失敗回滾
  • 隔離性(Isolation):數據併發的時候,一個事務所操作的數據在提交之前,對其他事務的可見性設定(一般設定爲不可見)
  • 一致性(Consistency):事務中操作的數據及狀態改變是一致的,即寫入資料的結果必須完全符合預設的規則,不會因爲出現系統意外等原因導致狀態的不一致
  • 持久性(Durability):事務所做的修改就會永久保存,不會因爲系統意外導致數據的丟失

事務併發

  • 在實際生活中,我們不可能總是在一個事務執行完以後再執行另一個事務,更多的是同時有許多事務一起提交,而這就叫作事務併發
    (試想一下,如果火車票購買只能是這個人買完了下個人才能買的話,你會遇到那種成百上千張車票在三秒內就沒了的場景嘛?)
  • 事務併發在提高效率的同時不可避免地會產生一些問題,如:
    • 髒讀:一個事務訪問到了另一個事務未提交的數據
      假設現在有3張車票,在3個人下訂單後我們更新了一下數據,即無車票;此時回家心切的小明查詢車票餘量,爲0張,悲傷不已;但是此時我們發現那三個人的訂單有問題,於是回滾了該事務,即仍有三張車票,此時就出現了髒讀
    • 不可重複讀:一個事務讀取同一條記錄兩次,得到的結果不一致,重點在於數據的修改
      假設現在有三張車票,此時回家心切的小明查詢了一下,發現還有三張車票,興奮極了,懷疑這是不是錯覺,於是重新刷新了一下,卻驚奇地發現沒有了!原來在他刷新的時候有三個人已經提交訂單購買車票了,而小明又陷入了深深的思考中。。。
    • 幻讀:一個事務讀取兩次,得到的記錄條數不一致,重點在於數據的增加或刪除
      (注:幻讀和不可重複讀大同小異,只不過其側重點不同而已)

隔離級別

爲了應對事務的併發所帶來的問題,可以通過設置數據庫的事務隔離級別來處理:

  • 讀未提交(read uncommitted):事務中的修改,即使沒有提交,其他事務也可以看得到,會產生“髒讀”、“幻讀”和“不可重複讀”等問題
  • 讀已提交(read committed):大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另一個並行事務已修改但未提交的數據,避免了“髒讀”,但避免不了“幻讀”和“不可重複讀”的問題
  • 可重複讀(repeatable read):保證了一個事務不會修改已經由另一個事務讀取但未提交(回滾)的數據,避免了“髒讀”和“不可重複讀”的問題,但不能避免“幻讀”,性能損失更大
  • 串行化(serializable):最嚴格的級別,事務串行執行,資源消耗最大
事務隔離級別 髒讀 不可重複讀 幻讀
讀未提交 可能 可能 可能
讀已提交 不可能 可能 可能
可重複讀 不可能 不可能 對InnoDB不可能
串行化 不可能 不可能 不可能

應用示例

  • 提交事務
begin; -- 開始提交事務
<語句>;
rollback; -- 出現異常則取消事務提交
commit; -- 事務提交完畢
begin; -- 開始提交事務 
insert into rental(rental_date,inventory_id,customer_id,return_date,staff_id)
values('2005-05-24 23:03:39', 367, 130, '2005-06-01 22:12:39', 1); -- 注意主外鍵約束 
insert into payment(customer_id,staff_id,rental_id,amount,payment_date)
values(130,1,16054,911,'2017-04-01 08:20:00');
rollback; -- 出現異常則取消事務提交  
commit; -- 事務提交完畢 
  • 顯示級別
select @@transaction_isolation;

在這裏插入圖片描述

  • 修改級別
set session transaction isolation level <隔離級別>; 
-- 隔離級別分爲 read uncommitted、read committed、repeatable read、serializable
set session transaction isolation level read uncommitted; 
-- 更改當前會話的事務隔離級別爲讀未提交

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章