MYSQL事務以及隔離級

2021-06-03 17:56:25 字數 3286 閱讀 1328

事務是一組原子性的sql查詢語句,也可以被看做乙個工作單元。如果資料庫引擎能夠成功地對資料庫應用所有的查詢語句,它就會執行所有查詢,如果任何一條查詢語句因為崩潰或其他原因而無法執行,那麼所有的語句就都不會執行。也就是說,事務內的語句要麼全部執行,要麼一句也不執行。

例:將b表中符合條件的記錄搬移到a表中(相似語句已在命令提示行中測試)

start transaction;//用start transaction語句開始乙個事務

insert into a select from b where ...;//將b表中符合條件的行記錄插入a表

delete from b where ...;//將b表中符合條件的行記錄刪除

commit; /rollback; //commit語句提交整個事務,永久地修改資料,rollback語句回滾整個事務,取消已做的修改

//如果插入操作失敗,那麼刪除操作將不執行

acid測試

acid:原子性(atomicity)、一致性(consistency)、隔離性(isolation)、永續性(durability)。乙個有效的事務處理系統必須滿足相關標準。

a.原子性:乙個事務必須被視為乙個單獨的內部「不可分」的工作單元,以確保整個事務要麼全部執行,要麼全部回滾。當乙個事務具有原子性時,該事務絕對不會被部分執行,要麼完全執行,要麼根本不執行。

b.一致性:資料庫總是從一種一致性狀態轉換到另一種一致性狀態。在上述例子中,一致性確保了,即使插入或者刪除操作失敗了,資料庫也不會多出或者丟失記錄。因為最終事務根本沒有被提交,任何事務處理過程中所做的資料改變,也不會影響到資料庫的內容。

c.隔離性:某個事務的結果只有在完成之後才對其他事務可見。在上述例子中,當資料庫執行完insert語句,還未執行delete語句時,如果此時另乙個客戶端對資料庫的訪問也同時執行,它將仍視符合條件的記錄在b表中。

d.永續性:一旦乙個事務提交,事務所做的資料改變將是永久的。

這種事務處理中的額外安全措施,導致資料庫伺服器要完成更多的額外工作。通常,乙個支援acid特性的資料庫,相對於不支援這種特性的資料庫,需要更強的cpu處理能力,更大的記憶體和更多的磁碟空間。這正是選用mysql儲存引擎架構的有利之處。使用者可以根據應用是否需要事務處理,選擇相應的儲存引擎。如果對於某些型別的資料查詢,使用者不需要真正的事務處理,他可以選擇乙個非事務處理型的儲存引擎來實現查詢,以獲得更高的處理效能。(我們的資料庫選擇的儲存引擎是innodb,支援事務處理,而mysql預設的儲存引擎是myisam引擎,不支援事務)

隔離級

sql標準定義了4類隔離級,包括了一些具體規則,用來限定事務內外的哪些改變時可見的,哪些是不可見的。低階別的隔離級一般支援更高的併發處理,並擁有更低的系統開銷。

read uncommitted(讀取未提交內容)

在read uncommitted隔離級,所有事務都可以「看到」未提交事務的執行結果。在這種級別上,可能會產生很多問題。本隔離級很少用於實際應用,因為它的效能也不比其他級別好多少,而別的級別還有其他更多的優點。讀取未提交資料,也被稱之為「髒讀(dirty read)」

read committed(讀取提交內容)

大多數資料庫系統的預設隔離級是read committed(但這不是mysql預設的)。它滿足了隔離的早先簡單定義:乙個事務在開始時,只能「看見」已經提交事務所做的改變,乙個事務從開始到提交前,所做的任何資料改變都是不可見的,除非已經提交。這種隔離級別也支援所謂的「不可重複讀(nonrepeatable read)」。這意味著使用者執行同一語句兩次,看到的結果是不同的。

repeatable read(可重讀)

repeatable read 隔離級解決了read uncommitted隔離級導致的問題。它確保同一事務的多個例項在併發讀取資料時,會「看到相同的」資料行。不過理論上,這會導致另乙個棘手問題:幻讀(phantom read)。簡單來說,幻讀指當使用者讀取某一範圍的資料行時,另乙個事務又在該範圍內插入了新行,當使用者再讀取該範圍的資料行時,另乙個事務又在該範圍內插入了新行,當使用者再讀取該範圍的資料行時,會發現有新的「幻影」行。innodb和falcon儲存引擎通過多版本併發控制機制解決了幻讀問題。 repeatable read 是mysql的預設事務隔離級。innodb和falcon儲存引擎都遵循這種設定。

serializable(可序列化)

serializable是最高端別的隔離級,它通過強制事務排斥,使之不可能相互衝突,從而解決幻讀問題。簡言之,serializable是在每個讀的資料行上加鎖。在這個級別,可能導致大量的超時現象和鎖競爭現象。很少看到有使用者選擇這種隔離級。

注:不可重複讀與幻讀:不可重複讀的重點是修改(同樣的查詢條件,你讀取過的資料,再次讀取出來發現值不一樣了);幻讀的重點在於新增或者刪除(同樣的查詢條件,第1次和第2次讀出來的記錄數不一樣)

檢視innodb系統級別的事務隔離級別:

mysql> select @@global.tx_isolation;

檢視innodb會話級別的事務隔離級別:

mysql> select @@tx_isolation;

mysql中的事務

autocommit(自動提交)

mysql預設操作模式是autocommit模式。這意味著除非顯示地開始乙個事務,否則它將把每個查詢視為乙個單獨事務自動執行。在當前連線中,可以通過變數設定,啟用和禁用autocommit模式。

mysql> show variables like 'autocommit'; //高版本的mysql支援

mysql> select @@autocommit; 支援

如果設定autocommit=0,使用者將一直處於某個事務中,直到使用者執行一條commit或rollback語句,之後,mysql將立即開始乙個新事務。

在事務中混合使用儲存引擎

在乙個事務中,如果混合使用事務性表和非事務性表,假如事務處理一切順利,那麼結果也會正常。但是,如果事務須回滾,那麼在非事務性表上做的修改將無法取消。這將導致資料庫處於資料不一致的狀態,在這種狀態下,很難對資料進行恢復,並且事務會變得懸而未決。

隱式和顯式鎖定

innodb使用二相鎖定協議(two-phase locking protocol兩段鎖協議)。乙個事務在執行過程中的任何時候,都可以獲得鎖,但只有在執行commit或rollback語句後,才可以釋放這些鎖。它會同時釋放掉所有鎖。以上描述的鎖定機制都是隱式鎖定。innodb會根據使用者的隔離級別,自動處理鎖定。不過innodb也支援顯示鎖定

MYSQL事務以及隔離級

事務是一組原子性的sql查詢語句,也可以被看做乙個工作單元。如果資料庫引擎能夠成功地對資料庫應用所有的查詢語句,它就會執行所有查詢,如果任何一條查詢語句因為崩潰或其他原因而無法執行,那麼所有的語句就都不會執行。也就是說,事務內的語句要麼全部執行,要麼一句也不執行。例 將b表中符合條件的記錄搬移到a表...

MYSQL事務以及隔離級

事務的概念 事務是一組原子性的sql查詢語句,也可以被看做乙個工作單元。如果資料庫引擎能夠成功地對資料庫應用所有的查詢語句,它就會執行所有查詢,如果任何一條查詢語句因為崩潰或其他原因而無法執行,那麼所有的語句就都不會執行。也就是說,事務內的語句要麼全部執行,要麼一句也不執行。例 將b表中符合條件的記...

mysql官 事物 MySQL事務以及隔離級別

read uncommitted 讀取未提交內容 在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,因為它的效能也不比其他級別好多少。讀取未提交的資料,也被稱之為髒讀 dirty read read committed 讀取提交內容 這是大多數資料庫系統的預設隔離...