mysql事务实战_MySQL - 实战 (2) - 事务隔离
MySQL - 實(shí)戰(zhàn) (2) - 事務(wù)隔離
1 事務(wù)相關(guān)概念
MySQL 中,事務(wù)支持是在引擎層實(shí)現(xiàn)的
MySQL 是一個支持多引擎的系統(tǒng),但并不是所有的引擎都支持事務(wù)
MySQL 原生的 MyISAM 引擎就不支持事務(wù),這也是 MyISAM 被 InnoDB 取代的重要原因之一
2 隔離級別
2.1 數(shù)據(jù)庫多事務(wù)同時執(zhí)行時可能產(chǎn)生的問題:
臟讀(dirty read)
讀到其他事務(wù)未提交的數(shù)據(jù)
幻讀(phantom read)
前后讀取的記錄內(nèi)容不一致
不可重復(fù)讀(non-repeatable read)
前后讀取的記錄數(shù)量不一致
隔離級別越高效率越低
2.2 隔離級別
讀未提交(read uncommitted)
讀未提交是指,一個事務(wù)還沒提交時,它做的變更就能被別的事務(wù)看到
讀提交(read committed)
讀提交是指,一個事務(wù)提交之后,它做的變更才會被其他事務(wù)看到
可重復(fù)讀(repeatable read)
可重復(fù)讀是指,一個事務(wù)執(zhí)行過程中看到的數(shù)據(jù),總是跟這個事務(wù)在啟動時看到的數(shù)據(jù)是一致的。當(dāng)然在可重復(fù)讀隔離級別下,未提交變更對其他事務(wù)也是不可見的
串行化(serializable )
串行化,顧名思義是對于同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”。當(dāng)出現(xiàn)讀寫鎖沖突的時候,后訪問的事務(wù)必須等前一個事務(wù)執(zhí)行完成,才能繼續(xù)執(zhí)行
在實(shí)現(xiàn)上,數(shù)據(jù)庫里面會創(chuàng)建一個視圖,訪問的時候以視圖的邏輯結(jié)果為準(zhǔn)。在“可重復(fù)讀”隔離級別下,這個視圖是在事務(wù)啟動時創(chuàng)建的,整個事務(wù)存在期間都用這個視圖。在“讀提交”隔離級別下,這個視圖是在每個 SQL 語句開始執(zhí)行的時候創(chuàng)建的。這里需要注意的是,“讀未提交”隔離級別下直接返回記錄上的最新值,沒有視圖概念;而“串行化”隔離級別下直接用加鎖的方式來避免并行訪問
2.3 事務(wù)隔離的實(shí)現(xiàn)
在 MySQL 中,實(shí)際上每條記錄在更新的時候都會同時記錄一條回滾操作 (undo log)。記錄上的最新值,通過回滾操作,都可以得到前一個狀態(tài)的值
同一條記錄在系統(tǒng)中可以存在多個版本,就是數(shù)據(jù)庫的多版本并發(fā)控制(MVCC)
回滾日志在不需要的時候才刪除,即當(dāng)系統(tǒng)里沒有比這個回滾日志更早的 read-view 的時候
2.4 長事務(wù)
2.4.1 盡量避免使用長事務(wù)
長事務(wù)意味著系統(tǒng)里面會存在很老的事務(wù)視圖。由于這些事務(wù)隨時可能訪問數(shù)據(jù)庫里面的任何數(shù)據(jù),所以這個事務(wù)提交之前,數(shù)據(jù)庫里面它可能用到的回滾記錄都必須保留,這就會導(dǎo)致大量占用存儲空間
在 MySQL 5.5 及以前的版本,回滾日志是跟數(shù)據(jù)字典一起放在 ibdata 文件里的,即使長事務(wù)最終提交,回滾段被清理,文件也不會變小
長事務(wù)還占用鎖資源
2.5 事務(wù)的啟動方式
2.5.1 方式一:顯示啟動
顯式啟動事務(wù)語句, begin 或 start transaction。配套的提交語句是 commit,回滾語句是 rollback
2.5.2 方式二
set autocommit=0,這個命令會將這個線程的自動提交關(guān)掉。意味著如果你只執(zhí)行一個 select 語句,這個事務(wù)就啟動了,而且并不會自動提交。這個事務(wù)持續(xù)存在直到你主動執(zhí)行 commit 或 rollback 語句,或者斷開連接
有些客戶端連接框架會默認(rèn)連接成功后先執(zhí)行一個 set autocommit=0 的命令。這就導(dǎo)致接下來的查詢都在事務(wù)中,如果是長連接,就導(dǎo)致了意外的長事務(wù)
使用 set autocommit=1, 通過顯式語句的方式來啟動事務(wù)
2.5.3 解決多一次交互問題
在 autocommit 為 1 的情況下,用 begin 顯式啟動的事務(wù)
執(zhí)行 commit work and chain,則是提交事務(wù)并自動啟動下一個事務(wù)
2.5.4 查詢長事務(wù)
information_schema 庫的 innodb_trx 這個表中查詢長事務(wù)
示例:查詢持續(xù)時間超過60s的長事務(wù)
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60
3 問題自我總結(jié)
1.事務(wù)的概念是什么?
2.mysql的事務(wù)隔離級別讀未提交, 讀已提交, 可重復(fù)讀, 串行各是什么意思?
3.讀已提交, 可重復(fù)讀是怎么通過視圖構(gòu)建實(shí)現(xiàn)的?
4.可重復(fù)讀的使用場景舉例? 對賬的時候應(yīng)該很有用?
5.事務(wù)隔離是怎么通過read-view(讀視圖)實(shí)現(xiàn)的?
6.并發(fā)版本控制(MCVV)的概念是什么, 是怎么實(shí)現(xiàn)的?
7.使用長事務(wù)的弊病? 為什么使用常事務(wù)可能拖垮整個庫?
8.事務(wù)的啟動方式有哪幾種?
9.commit work and chain的語法是做什么用的?
10.怎么查詢各個表中的長事務(wù)?
11.如何避免長事務(wù)的出現(xiàn)?
總結(jié)
以上是生活随笔為你收集整理的mysql事务实战_MySQL - 实战 (2) - 事务隔离的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 临时表 概念_临时表的概念
- 下一篇: 服务器版的mysql怎么装_WIN7服务