問題列表:
1.spring事務是怎麼實現的?
2.有人說開啓了事務的方法就不會有多線程問題對不對?
3.mysql如何實現事務的acid的?
4.mysql在滿足數據的事務特性又做了哪些設計來提高併發?
下面我針對這幾個問題談談自己的理解:
1.spring事務是怎麼實現的
首先大家都知道spring事務是使用的aop來實現的,那spring容器又是怎麼設計的,他是通過beanfactorypostProcess重新修改了beandifinition把這個功能賦給bean的
2.開啓了事務的方法依然會有多線程問題
spring事務只負責傳播行爲的設計,只是在方法的開始和增加了回滾,提交特性,比如 開始執行方法A ->開啓事務->方法b->方法c->事務提交,保證了在這個過程事務的原子性,如果b方法引用了外部的全局變量在多線程執行下還是有數據問題的
3.mysql如何實現事務的acid的
先說下acid的特性:
-
原子性(Atomicity,或稱不可分割性)
-
一致性(Consistency)
-
隔離性(Isolation)
-
持久性(Durability)
1.通過redolog來實現持久性:
當事務提交(COMMIT)時,必須先將該事務的所有日誌寫入到重做日誌文件進行持久化redo log file,待事務的COMMIT操作完成纔算完成
2.undo log 來實現事務原子性
原子性在於事務回滾可以保證撤銷所有的執行過的sql;
當事務對數據庫進行修改時,InnoDB 會生成對應的 undo log;
如果事務執行失敗或調用了 rollback,導致事務需要回滾,便可以利用 undo log 中的信息將數據回滾到修改之前的樣子;
undo log 屬於邏輯日誌,它記錄的是 sql 執行相關的信息。當發生回滾時,InnoDB 會根據 undo log 的內容做與之前相反的工作;
3.mysql innodb通過鎖機制,mvcc實現隔離性(和具體的隔離級別有關係)
這邊要講的就太多了,後續會開新的篇幅來講解,我這邊先做個總結:rr隔離級別通過鎖和mvcc(實現原理也是undolog來做的)實現的,rc的隔離較低會有不可重複讀問題;
4.一致性
mysql數據一致性的保障其實要靠前面三個,如果保障不了前面三個就可能會有數據不一致的問題,另外數據的一致性也需要應用層來保障比如轉賬:a,b兩個賬戶轉賬總的數據不能少
4.mysql在滿足數據的事務特性又做了哪些設計來提高併發?
這邊談論的前提條件是:innodb+RR隔離級別
mysql的RR隔離級別是和概念上的rr不一樣,它不僅滿足可重複讀,而且解決了幻讀(這點很多人不知道),怎麼實現的呢:
1.mysql提供了行鎖,間隙鎖,臨建鎖等各種鎖來保證
2.mysql打破了2pc原則,一階段查詢的記錄不滿足條件的數據會釋放掉鎖
3.mysql針對快照讀比如普通的select使用了mvcc數據多版本的無鎖設計來提高併發,針對select for update等加鎖
4.其他..我暫時還沒研究到