MySQL事務,這篇文章就夠了

原文連接:https://blog.ouyangsihai.cn/ >> MySQL事務,這篇文章就夠了html

在看這篇文章以前,咱們回顧一下前面的幾篇關於MySQL的系列文章,應該對你讀下面的文章有所幫助。java

0 什麼是事務

事務(Transaction) 是併發控制的基本單位。所謂的事務,它是一個操做序列,這些操做要麼都 執行,要麼都不執行,它是一個不可分割的工做單位。事務是數據庫維護數據一致性的單位,在每 個事務結束時,都能保持數據一致性。mysql

同時,事務有着嚴格的地定義,必須知足四個特性,也就是咱們一直說的ACID,可是,並非說各類數據庫就必定會知足四個特性,對於不一樣的數據庫的實現來講,在不一樣程度上是不必定徹底知足要求的,好比,Oracle數據庫來講,默認的事務隔離級別是READ COMMITTED,是不知足隔離性的要求的。面試

下面咱們趁熱打鐵,介紹一下事務的必知必會的四大特性,這幾個特性也是在面試中,面試官面試MySQL的相關知識的時候,問的比較多的問題,因此,這幾個特性務必須要理解而且透徹的記在內心,開個玩笑,被火車撞了,也不該該忘記這四個特性!sql

1 事務的四大特性

事務的四大特性簡稱爲:ACID,分別是原子性、一致性、隔離性和持久性數據庫

下面咱們一一來介紹一下。微信

  • 原子性(Atomicity)

原子性指的是整個數據庫的事務是一個不可分割的工做單位,每個都應該是一個原子操做。網絡

當咱們執行一個事務的時候,若是一系列的操做中,有一個操做失敗了,那麼,須要將這一個事務中的全部操做恢復到執行事務以前的狀態,這就是事務的原子性。併發

下面舉個簡單的例子。分佈式

i++;複製代碼

上面這個最簡單不過的代碼常常也會被問到,這是一個原子操做嗎?那確定不是,若是咱們把這個代碼放到一個事務中來講,當i+1出現問題的時候,回滾的就是整個代碼i++(i = i + 1)了,因此回滾以後,i的值也是不會改變的。

以上就是原子性的概念。

  • 一致性(consistency)

一致性是指事務將數據庫從一種狀態轉變爲下一種一致性的狀態,也就是說在事務執行先後,這兩種狀態應該是同樣的,也就是數據庫的完整性約束不會被破壞。

另外,須要注意的是一致性是不關注中間狀態的,好比銀行轉帳的過程,你轉帳給別人,至於中間的狀態,你少了500 ,他多了500,這些中間狀態不關注,若是分屢次轉帳中間狀態也是不可見的,只有最後的成功或者失敗的狀態是可見的。

若是到分佈式的一致性問題,又能夠分爲強一致性、弱一致性和最終一致性,關於這些概念,能夠本身查查,仍是頗有意思的。

  • 隔離性(isolation)

事務咱們是能夠開啓不少的,MySQL數據庫中能夠同時啓動不少的事務,可是,事務和事務之間他們是相互分離的,也就是互不影響的,這就是事務的隔離性

  • 持久性(durability)

事務的持久性是指事務一旦提交,就是永久的了,就是發生問題,數據庫也是能夠恢復的。所以,持久性保證事務的高可靠性。

2 事務的分類

事務能夠分爲不少中類型,通常分爲:扁平事務、帶有保存點的扁平事務、鏈事務、嵌套事務、分佈式事務

扁平事務

扁平事務是最簡單的一種,在實際開發中也是使用的最多的一種事務。在這種事務中,全部操做都處於同一層次,最多見的方式以下:

BEGIN WORK
Operation 1
Operation 2
Operation 3
...
Operation N
COMMIT WORK複製代碼

舉個例子

begin work;

select * from user;

update user set name = 'sihai' where id = 1;

commit work;複製代碼

扁平事務的主要缺點是不能提交或回滾事務的某一部分,或者分幾個獨立的步驟去提交。

帶有保存點的扁平事務

這種事務除了支持扁平事務支持的操做外,這種事務跟扁平事務最大的區別就是容許在事務執行過程當中回滾到同一事務中較早的一個狀態,這是由於可能某些事務在執行過程當中出現的錯誤並不會對全部的操做都無效,放棄整個事務不合乎要求,開銷也太大。保存點用來通知系統應該記住事務當前的狀態,以便之後發生錯誤時,事務能回到該狀態。

舉個例子

begin work;

select * from user;

savepoint t1;

update user set name = 'sihai' where id = 1;

savepoint t2;

commit work;複製代碼

經過上面的方式咱們就創建了兩個保存點t一、t2,經過ROLLBACK TO SAVEPOINT t1,咱們就能夠返回到保存點t1

鏈事務

鏈事務:在提交一個事務時,釋放不須要的數據對象,將必要的處理上下文隱式的傳給下一個要開始的事務。須要注意,提交事務操做和下一個事務操做將合併爲一個原子操做,就是下一個事務能夠看到上一個事務的結果。

鏈事務,就是指回滾時,只能恢復到最近一個保存點;而帶有保存點的扁平事務則能夠回滾到任意正確的保存點。

舉個例子

begin work;

select * from user;

savepoint t1;

update user set name = 'sihai' where id = 1;

savepoint t2;

commit work;複製代碼

仍是這個例子,可是對於鏈事務來講,是不能直接rollback到保存點t1的,最能恢復到最近的一個保存點t2;另外咱們須要注意,鏈事務在執行commit後就會釋放當前事務所持有的全部鎖,而帶有保存點的扁平事務不會影響所持有的鎖。

嵌套事務

在事務中再嵌套事務,這種結構有點像一顆橫着的樹的結構,位於根節點的事務稱爲頂層事務。事務的前驅稱爲父事務,其它事務稱爲子事務。事務的前驅稱爲父事務,事務的下一層稱爲子事務。

子事務既能夠提交也能夠回滾,可是它的提交操做並不立刻生效,除非由其父事務提交。所以就能夠肯定,任何子事務都在頂層事務提交後才真正的被提交了。同理,任意一個事務的回滾都會引發它的全部子事務一同回滾。

BEGIN WORK
     SubTransaction1:
             BEGIN WORK
                 SubOperationX
             COMMIT WORK
     SubTransaction2:
             BEGIN WORK
                 SubOperationY
             COMMIT WORK
     ...
     SubTransactionN:
             BEGIN WORK
                 SubOperationN
             COMMIT WORK
COMMIT WORK複製代碼

分佈式事務

分佈式事務一般是指在一個分佈式環境下運行的扁平事務,所以須要根據數據所在位置訪問網絡中的不一樣節點。

在不一樣的物理地址,經過網絡訪問,執行不一樣的事務,這就是分佈式事務。

3 事務的使用

首先這一部分咱們仍是先介紹一下這些事務的語句,也不是不少,使用也不復雜,下面用一個表格作一個整理。

注意COMMITCOMMIT WORK語句不一樣之處在於COMMIT WORK用來控制事務結束後的行爲是CHAIN仍是RELEASE,若是是CHAIN,那麼事務就是鏈事務

用戶能夠經過參數completion_type控制,以下:

  • completion_type = 1 實例

執行下面的操做;

SET @@completion_type = 1;

BEGIN WORK;

INSERT INTO lock_test SELECT 10;

COMMIT WORK;複製代碼

接着咱們再執行下面的操做;

INSERT INTO lock_test SELECT 115;

ROLLBACK;

 SELECT * FROM lock_test;複製代碼

咱們先插入一條數據115,而後再回滾,咱們知道若是不是在一個事務的時候,115應該是會插入成功的,就算咱們回滾了,可是,這裏咱們回滾以後,查詢結果以下:

這個時候並無115這條記錄,也就是回滾生效了,說明在COMMIT WORK以後,又是一個新的事務,因此纔會出現這樣的結果。

  • completion_type = 2 實例

咱們先進行下面的操做;

SET @@completion_type = 2;

BEGIN WORK;

INSERT INTO lock_test SELECT 5;

COMMIT WORK;複製代碼

上面咱們已經提交事務了,當咱們使用下面的語句查詢lock_test的數據的時候,就會出現**斷開鏈接**。

SELECT * FROM lock_test;複製代碼

4 事務的隔離級別

事務的隔離級別有四種分別是:

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

對於這幾種隔離級別會帶來的問題及總結,能夠查看這篇文章:MySQL的又一神器-鎖,MySQL面試必備

5 總結

這篇文章從下面幾個內容介紹了一下MySQL數據庫事務的內容,更詳細的其餘內容在後面的文章中再講解。

  • 概念
  • 事務類型
  • 事務使用
  • 事務的隔離級別

文章有不當之處,歡迎指正,若是喜歡微信閱讀,你也能夠關注個人微信公衆號好好學java,獲取優質學習資源。

本文由博客一文多發平臺 OpenWrite 發佈!

相關文章
相關標籤/搜索