MySQL之事務及并發控制

事務主要用于處理操作量大,復雜度高的數據。比如說,在人員管理系統中,你刪除一個人員,你既需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數據庫操作語句就構成一個事務

本節索引:

一、事務Transaction

二、事務的隔離級別

三、并發控制

四、MVCC-多版本的并發控制協議

 

P4~]9M%RV3AX4REIP)1`EVP

一、事務

什么是事務?

事務Transactions:一組原子性的SQL語句,或一個獨立工作單元。

事務主要用于處理操作量大,復雜度高的數據。比如說,在人員管理系統中,你刪除一個

人員,你既需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,

這樣,這些數據庫操作語句就構成一個事務

 

事務日志:記錄事務信息,實現undo,redo等故障恢復功能

 

ACID特性:

A:atomicity原子性;

整個事務中的所有操作要么全部成功執行,要么全部失敗后回滾,不可能停滯在中間某個環節。

 

C:consistency一致;

數據庫總是從一個一致性狀態轉換為另一個一致性狀態

也就是說:如果事務是并發多個,系統也必須如同串行事務一樣操作。其主要特征是保護性和不

變性(Preserving an Invariant),以轉賬案例為例,假設有五個賬戶,每個賬戶余額是100元,那

么五個賬戶總額是500元,如果在這個5個賬戶之間同時發生多個轉賬,無論并發多少個,比如在

A與B賬戶之間轉賬5元,在C與D賬戶之間轉賬10元,在B與E之間轉賬15元,五個賬戶總額也應該

還是500元,這就是保護性和不變性

 

I:Isolation隔離性

一個事務所做出的操作在提交之前,是不能為其它事務所見;隔離有多種隔離級別,實現并發。

如果有兩個事務,運行在相同的時間內,執行相同的功能,事務的隔離性將確保每一事務在系統中

認為只有該事務在使用系統。這種屬性有時稱為串行化,為了防止事務操作間的混淆,必須串行化

或序列化請求,使得在同一時間僅有一個請求用于同一數據。

 

D:durability持久性

一旦事務提交,其所做的修改會永久保存于數據庫中

 

事務生命周期

如圖所示一個事務的生命周期:

(1) 開啟一個事務

(2) 進行事務操作,注:只有對數據庫的增、刪、改操作才記入事務,SELECT查

詢語句不計入事務。

(3) ROLLBACK將會使未提交的數據回滾,數據還原至更改前的數據

(4) 一旦進行了COMMIT提交,新的數據將會持久的保存在數據庫之中,并不會被回

滾,即事務的持久性。

 

 

事務控制語句:

BEGINSTART TRANSACTION顯式地開啟一個事務;

 

ROLLBACK:回滾會結束用戶的事務,并撤銷正在進行的所有未提交的修改;

 

COMMIT:提交事務,并使已對數據庫進行的所有修改稱為永久性的;

 

SAVEPOINT identifier:SAVEPOINT允許在事務中創建一個保存點,一個事務中可以有多個SAVEPOINT;

 

ROLLBACK TO identifier:把事務回滾到標記點;

 

RELEASE SAVEPOINT identifier:刪除一個事務的保存點,當沒有指定的保存點時,執行該語句會拋出一個異常;

 

 

實現MySQL事務處理:

方法一:用 BEGIN, ROLLBACK, COMMIT來實現

BEGIN 開始一個事務

 

ROLLBACK 事務回滾

 

COMMIT 事務確認

 

方法二:直接用 SET 來改變 MySQL 的自動提交模式:

 

SET AUTOCOMMIT=OFF 禁止自動提交

 

SET AUTOCOMMIT=ON? 開啟自動提交(系統默認項)

 

示例:事務測試

M40SD}~}HE((AK_QBQ[0}%W

 

二、事務隔離級別

在數據庫操作中,為了有效保證并發讀取數據的正確性,提出的事務隔離級別。

數據庫是要被廣大客戶所共享訪問的,那么在數據庫操作過程中很可能出現以下幾種不確定情況。

更新丟失

兩個事務都同時更新一行數據,一個事務對數據的更新把另一個事務對數據的更新覆蓋了。這是因為系統

沒有執行任何的鎖操作,因此并發事務并沒有被隔離開來。

 

臟讀

一個事務讀取到了另一個事務未提交的數據操作結果。這是相當危險的,因為很可能所有的操作都被回

滾。

 

虛讀

事務T1讀取某一數據后,事務T2對其做了修改,當事務T1再次讀該數據時得到與前一次不同的值。

 

幻讀

事務在操作過程中進行兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的數據或者缺少了第一次

查詢中出現的數據(這里并不要求兩次查詢的SQL語句相同)。這是因為在兩次查詢過程中有另外一個事

務插入數據造成的。

 

事務隔離級別

為了避免上面出現的幾種情況,在標準SQL規范中,定義了4個事務隔離級別,不同的隔離級別對事務的

處理不同。

從上至下更加嚴格:

READ UNCOMMITTED:可讀取到未提交數據,產生臟讀

 

READ COMMITTED:可讀取到提交數據,但未提交數據不可讀,產

生不可重復讀,即可讀取到多個提交數據,導致每次讀取數據不一致

 

REPEATABLE READ 可重復讀,多次讀取數據都一致,產生幻讀,即

讀取過程中,即使有其它提交的事務修改數據,仍只能讀取到未修改

前的舊數據。此為MySQL默認設置

 

SERIALIZABILE 可串行化,未提交的讀事務阻塞修改事務,或者未

提交的修改事務阻塞讀事務。導致并發性能差

 

隔離級別對比

 

管理事務隔離級別:

服務器變量tx_isolation指定

默認為REPEATABLE-READ,可在GLOBAL和SESSION級進行設置

SET tx_isolation=”

? ? ? ? ? ? ? READ-UNCOMMITTED

? ? ? ? ? ? ? READ-COMMITTED

? ? ? ? ? ? ? REPEATABLE-READ

? ? ? ? ? ? ? SERIALIZABLE

服務器選項中指定

vim /etc/my.cnf

[mysqld]

transaction-isolation=SERIALIZABLE

 

 

 

三、并發控制

鎖粒度:

表級鎖

行級鎖

鎖:

讀鎖:共享鎖,只讀不可寫,多個讀互不阻塞,

寫鎖:獨占鎖,排它鎖,一個寫鎖會阻塞其它讀和它鎖

實現:

存儲引擎:自行實現其鎖策略和鎖粒度

服務器級:實現了鎖,表級鎖;用戶可顯式請求

分類:

隱式鎖:由存儲引擎自動施加鎖

顯式鎖:用戶手動請求

 

鎖策略:在鎖粒度及數據安全性尋求的平衡機制

顯示使用鎖

? LOCK TABLES

tbl_name [[AS] alias] lock_type

???????? [, tbl_name [[AS] alias] lock_type] …

???????? lock_type: READ , WRITE

解鎖

UNLOCK TABLES

 

FLUSH TABLES tb_name[,…] [WITH READ LOCK]?

關閉正在打開的表(清除查詢緩存),通常在備份前加全局讀鎖

SELECT clause [FOR UPDATE | LOCK IN SHARE MODE]

查詢時加寫或讀鎖

 

讀鎖:

讀鎖也稱為共享鎖,讀鎖允許多個連接可以同一時刻并發的讀取同一資源,互不干擾;

添加讀鎖:

MariaDB [hellodb]>?lock tables teachers read;

 

寫鎖:

寫鎖也稱為排他鎖,一個寫鎖會阻塞其他的寫鎖或讀鎖,保證同一時刻只有一個連接可以寫入數據,同時

防止其他用戶對這個數據的讀寫。

添加寫鎖:

MariaDB [hellodb]>?lock tables students write;

 

 

死鎖:

兩個或多個事務在同一資源相互占用并請求鎖定對方占用的資源的狀態

如下所示:

事務1 ? ? ? ? ? ? ? ? ? ?事務2

update table1??? update table2

update table2 ? ?update table1

產生死鎖

 

四、MVCC-多版本的并發控制協議

MySQL InnoDB存儲引擎,實現的是基于多版本的并發控制協議——MVCC?(Multi-Version

?Concurrency Control)?(注:與MVCC相對的,是基于鎖的并發控制,Lock-Based

Concurrency Control)。MVCC最大的好處,相信也是耳熟能詳:讀不加鎖,讀寫不沖突。

在讀多寫少的OLTP應用中,讀寫不沖突是非常重要的,極大的增加了系統的并發性能。

 

InnoDB在每行數據都增加兩個隱藏字段,一個記錄創建的版本號,一個記錄刪除的版本號。

 

* SELECT

當隔離級別是REPEATABLE READ時select操作,InnoDB必須每行數據來保證它符合兩個條件:

1、InnoDB必須找到一個行的版本,它至少要和事務的版本一樣老(也即它的版本號不大于

事務的版本號)。這保證了不管是事務開始之前,或者事務創建時,或者修改了這行數據的

時候,這行數據是存在的。

2、這行數據的刪除版本必須是未定義的或者比事務版本要大。這可以保證在事務開始之前

這行數據沒有被刪除。

符合這兩個條件的行可能會被當作查詢結果而返回。

* INSERT<br>InnoDB為這個新行記錄當前的系統版本號。

* DELETE<br>InnoDB將當前的系統版本號設置為這一行的刪除ID。

* UPDATE<br>InnoDB會寫一個這行數據的新拷貝,這個拷貝的版本為當前的系統版本號。

它同時也會將這個版本號寫到舊行的刪除版本里。

 

 

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/100886

(2)
wangxczwangxcz
上一篇 2018-06-12
下一篇 2018-06-12

相關推薦

  • 加密與安全

    申請證書& ssh 服務基于key驗證

    2018-05-19
  • liunx常用命令

    【1】創建文件和文件夾

    2018-04-03
  • 馬哥學堂的第二周

    1、Linux上的文件管理類命令都有哪些,其常用的使用方法及其相關示例演示。 cp? ? 將一份文件復制到其他目錄之中 使用-r 可實現遞歸復制。遞歸復制,可將一個目錄下的文件,復制到另一個目錄下。 rm? 用于刪除文件,使用-f可強制刪除。 mv 將一個文件移動到另一個目錄下。若在同一個目錄下使用mv,可實現更名。 cat 顯示文件內容。 wc 顯示文件的…

    2018-05-20
  • 馬哥Linux第二周作業

    第二周作業(6.25-7.1)

    Linux筆記 2018-06-30
  • 多種協議到網絡配置

    第五周總結、協議、網絡基礎、路由的配置等

    2018-05-08
  • Linux運維命令以及概念整理總結(1)

    1、文件系統分層結構: LBS Linux Standard Base
    2、ls命令、wc命令、時間戳、stat、通配符glob
    3、touch、cp、mv、rm、批量改名rename
    4、tree、mkdir、rmdir
    5、節點編號inode以及節點表、硬鏈接以及軟鏈接
    6、file命令、標準輸入,標準輸出

    2018-04-14
欧美性久久久久