事務隔離機制
事務就是要保證一組數據庫操作,要麼全部成功,要麼全部失敗。
在mysql中,事務支持是在引擎層實現的。
mysql是一個支持多引擎的系統,但並不是所有引擎都支持事務,比如mysql原生的MyISAM就不支持事務。這也是MyISAM被innoDB取代的重要原因。
隔離性與隔離級別
事務的四個特性: ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔離性、持久性). 這裏重點討論隔離性。
關於串行化的串行提交
關於串行化的串行提交:
串行化:通過讀寫鎖來避免並行訪問。
讀-讀:允許併發執行
讀-寫: 貌似也能併發執行。因此讀的那個事務中讀的是已提交的內容。
寫-寫:只能串行
什麼時候需要"可重複讀"的場景呢
假設你在管理一個個人銀行賬戶表。一個表存了每個月月底的餘額,一個表存了賬單明細。這時候你要做數據校對,也就是判斷上個月的餘額和當前餘額的差額,是否與本月的賬單明細一致。你一定希望在校對過程中,即使有用戶發生了一筆新的交易,也不影響你的校對結果。
這時候使用“可重複讀”隔離級別就很方便。事務啓動時的視圖可以認爲是靜態的,不受其他事務更新的影響。
事務隔離的實現
以可重複讀爲例,來看事務隔離的具體實現。
事務的啓動方式
MySQL 的事務啓動方式有以下幾種:
1. 顯式啓動事務語句: begin 或 start transaction.配套的提交語句是 commit,回滾語句是 rollback.
2. set autocommit=0,這個命令會將這個線程的自動提交關掉。意味着如果你只執行一個 select 語句,這個事務就啓動了,而且並不會自動提交。這個事務持續存在直到你主動執行 commit 或 rollback 語句,或者斷開連接。
有些客戶端連接框架會默認連接成功後先執行一個 set autocommit=0 的命令。這就導致接下來的查詢都在事務中,如果是長連接,就導致了意外的長事務。建議你總是使用 set autocommit=1, 通過顯式語句的方式來啓動事務。
你可以在 information_schema 庫的 innodb_trx 這個表中查詢長事務。
-- 查找持續時間超過 60s 的事務
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60;
如何避免長事務
參考
極客時間《mysql實戰45講》