事務隔離

事務就是保證一組數據庫操做,要麼所有成功,要麼所有失敗。
MySQL 中事務支持都是在引擎層實現的
MySQL 是一個支持多引擎的系統,但並非全部的引擎都支持事務數據庫

隔離級別出現的緣由是,當數據庫上有多個事務同時執行的時候,就可能出現髒讀(dirty read)、不可重複讀(non-repeatable read)、幻讀(phantom read)的問題,爲了解決這些問題,就有了 「隔離級別」 的概念。不一樣隔離級別數據庫行爲有所不一樣。併發

隔離級別越高,效率就越低。不少時候要在兩者之間找一個平衡點。
隔離級別包括:讀未提交(read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(serializable)ide

讀未提交:一個事務還沒提交時,它作的變動就能被別的事務看到
讀提交:一個事務提交以後,它作的變動纔會被其餘事務看到
可重複讀:一個事務執行過程當中看到的數據,老是跟這個事務在啓動的時候看到的數據是一致的。固然在可重複讀隔離級別下,未提交變動對其餘事務也是不可見。
串行化:顧名思義是對於同一行記錄,「寫」會加「寫鎖」,「讀」會加「讀鎖」。當出現讀寫鎖衝突的時候,後訪問的事務必須等前一個事務執行完成,才能繼續執行。線程

實例說明:各隔離級別日誌

各隔離級別的實現,數據庫裏會建立一個視圖,訪問的時候以視圖的邏輯爲準。
「可重複讀」 隔離級別下,這個視圖是在事務啓動時建立,整個事務存在期間都用這個視圖。
在「讀提交」 隔離級別下,這個視圖是在每一個 SQL 語句開始執行的時候建立的。
「讀未提交」 隔離級別下直接返回記錄上的最新值,沒有視圖概念。
「串行化」 隔離級別下直接用加鎖的方式來避免並行訪問。orm

隔離級別的配置方式是,transaction-isolation ,能夠用 show variables 查看當前值。事務

事務隔離的實現it

在 MySQL 中,實際上每條記錄在更新的時候都會同時記錄一條回滾操做。記錄上的最新值,經過回滾操做,均可以獲得前一個狀態的值。io

不一樣時刻啓動的事務會有不一樣的 read-view,同一條記錄在系統中能夠存在多的版本,就是數據庫的多版本併發控制(MVCC)。
要獲得那個 read-view 的值就必須將當前值依次執行全部的回滾操做獲得innodb

當沒有事務在須要用到這些回滾日誌時,回滾日誌會被刪除。

當系統裏沒有比這個回滾日誌更早的 read-view 的時候,就會刪除這個回滾日誌。

儘可能不要使用長事務,長事務意味着系統裏面會有很老的事務視圖,會佔用大量的存儲空間。

事務的啓動方式
1,顯示啓動事務語句,begin 或 start transaction。配套的提交語句是 commit ,回滾語句是 rollback 。
2,setautocommit=0 , 這個命令會將這個線程的自動提交關掉。意味着若是你只執行一個 select 語句,這個事務就啓動了,並且並不會自動提交。這個事務持續存在直到你主動執行 commit 或 rollback 語句,或者斷開鏈接。

能夠用 information_schema 庫的 innodb_trx 這個表中查詢長事務。好比下面這個語句查詢持續時間超過 60s 的事務select * from information_schema.innodb_trx where TIME_TO_SEC(timediFF(now(),trx_started))>60

相關文章
相關標籤/搜索