文章目錄
- @[TOC](文章目錄)
- 一、基本概念
- 二、事務的操作
- 1.設置全局事務隔離級別
- 2.設置事務提交方式
- 3.事務操作
- 三、事務隔離性
- 1.隔離性概念
- 2 .隔離級別設置
- 四、MVCC多版本控制
- 2. read view
文章目錄
- @[TOC](文章目錄)
- 一、基本概念
- 二、事務的操作
- 1.設置全局事務隔離級別
- 2.設置事務提交方式
- 3.事務操作
- 三、事務隔離性
- 1.隔離性概念
- 2 .隔離級別設置
- 四、MVCC多版本控制
- 2. read view
一、基本概念
事務是由若干條具有邏輯相關性的SQL語句組成的,用來完成某種任務的**邏輯單元.**事務具有原子性,一致性,隔離性,持久性4大屬性.
原子性:保證事務要么不執行,要么執行完,如果發生錯誤就回滾到事務發生前的狀態,就跟事務沒有發生一樣.
一致性:保證事務執行前和執行后,數據庫的完整性不會被破壞.其他事務看到的數據庫是一致的,不會看到事務執行過程中的不確定的數據,一致性是由原子性保證的,與用戶邏輯強相關,由用戶決定,如果因為用戶邏輯導致事務中有的SQL語句沒有成功執行,就會造成數據庫的不一致.
隔離性:事務操作的數據對于其他事務是隔離的.不會影響其他事務,也不會被其他事務影響.
持久性:事務的結果在數據庫中永久有效,不會因為數據庫故障被破壞.
事務存在的意義是為了方便上層應用程序的使用,有了事務,應用程序層面就不需要關系,數據庫操作失敗應該怎么做,并發訪問數據庫應該怎么做,只需要關心怎么操作數據庫,操作過程中的各種問題不需要關心.簡化了應用程序的編程模型.
不同的存儲引擎支持事務的情況不同.MySQL只有innodb支持事務.myisam不支持事務.show engines\G可以查看存儲引擎屬性信息.
事務的提交方式有自動提交和手動提交兩種,show variables like ‘autocommit’;語句可以查看事務提交方式ON為自動提交,OFF為手動提交set autocommit=1設置自動提交,set autocommit=0設置手動提交
二、事務的操作
1.設置全局事務隔離級別
set global transation isolation level read uncommitted 設置事務隔離級別,設置完畢需要重啟終端.
select @@tx_isolation;查看事務隔離級別
2.設置事務提交方式
autocommit=0為非自動提交,1為自動提交方式
3.事務操作
手動啟動事務begin或者start transaction
事務回滾savepoint 變量名,設置保存點,rollback,回滾.回滾操作可以全部回滾,也可以回滾到保存點,回滾到保存點,保存點之后的數據全部清除,保留之前的數據.
提交事務commit,提交之后事務就無法再回滾了,如果SQL發生異常程序退出時,SQL會自動回滾到事務開始的時候,與是否自動提交無關.
單個SQL語句也構成事務,當設置自動提交時,每條SQL語句執行完會自動提交,反之需要commit手動提交.
三、事務隔離性
1.隔離性概念
因為事務并發執行需要保持事務的原子性,保證多事務并發時不互相干擾,所以有了隔離性,因為允許事務執行時更具情況,可以收到不同程度的干擾,所有有了隔離級別.
事務隔離級別有4中,讀未提交,讀提交,可重復讀,串行化.
臟讀:一個用戶事務中讀到的數據是其他用戶事務未提交的事務,這叫做臟讀.
不可重復讀, 兩個事務并發執行,一個事務執行期間操作的數據因為另一個事務的提交發生了改變,導致結果出現差錯叫做不可重復讀.
**幻讀:**在可重復讀的隔離級別下,仍然可以讀到新插入并且已提交的數據.
串行化:是事務級別的串行,對每個讀的數據行加共享鎖,插入,刪除,修改都是串行的.
2 .隔離級別設置
設置全局隔離級別,會影響所有終端的隔離級別.
設置會話隔離級別,默認與全局隔離級別一致
查看隔離級別
四、MVCC多版本控制
概念: MVCC是用來解決讀寫沖突的無鎖并發控制.
事務結構: 每個事務都由數據,事務id,隱式主鍵id,flag標志,回滾指針組成.MySQL內部還維護了一個緩沖區undo log.
flag: 使用delete刪除數據不是真的刪除數據,而是將數據flag設置為刪除,這是出于數據恢復,刪除需要移動數據等多方面考慮.
回滾操作: undo log 中存儲了與實際寫入操作相反的操作,回滾時,執行想反操作即可,例如實際執行insert語句,會在undo log中記錄delete語句.
版本鏈: 每執行一條更新操作,會在undo log中記錄數據項的歷史版本,然后將歷史版本數據項在undo log中的地址記錄在已經更新的數據項的回滾指針表項中.多個歷史版本就形成版本鏈,一個版本也叫一個快照,讀歷史版本也叫快照讀.事務提交了,與事務相關,但是與其他
**讀寫操作并發執行: ** 使用讀未提交隔離級別,雙方都是當前讀(讀到的是最新的數據).如果是讀提交,一個事務是當前讀,一個是快照讀.因為讀的不是一個數據所以不用加鎖,從根本上解決了幻讀和臟讀和不可重復讀的問題.
2. read view
**概念: ** read view是事務進程快照讀時創建的一個用于快照可見性判斷的類,重要組成成員屬性有m_low_limit_id,m_up_limit_id,m_create_trx_id,m_ids;
**m_low_limit_id: ** 高水位,表示與當前事務同時運行事務的id中最大一個事務id加1;
**m_up_limit_id: ** 低水位,表示與當前事務同時運行事務的id中最小的一個事務id;
**m_create_trx_id: ** 當前事務的id;
**m_ids: ** 與當前事務同時在運行的所有事務id;
**檢查規則: ** 快照讀時會用readview類中的數據對比版本鏈中數據,如果快照id小于低水位,說明是當前事務運行前就已經提交的數據,或者是id等于m_create_trx_id說明是當前事務的快照,應該看見.如果快照id大于等于高水位,說明該事務是在當前事務運行之后才出現的,不應該被看見.如果m_ids是空說明就當前一個事務在運行,那么所有快照都能被看見.如果快照id在m_ids中說明事務仍在活躍,不應該被看見,如果不在m_ids中說明事務已提交,可以被看見.
可重復讀原理: 當事務進行快照讀的時候,會創建一個readview對象,一直到當前事務結束都是用一個readview,此時與當前事務同時運行的事務的操作對于當前事務而言是不可見的,就算其他事務在當前事務執行期間結束,readview中仍然會哪些事務當做正在運行的事務,也是不可見的.
**讀提交: ** 當前事務每次快照讀都會創建新的readview,與當前事務同時運行的其他事務在沒有提交前事務id是記錄在m_ids中的,提交后當前事務再次快照讀將重新創建readview,已經結束的事務id就不會出現在readview中,那么該事務的快照是可見的,就形成了讀提交.