数据库的锁事务
鎖
鎖的分類
1. 按照鎖的粒度分:
表鎖 行鎖
2. 鎖的類型分:
共享鎖:也叫做share鎖/S鎖 特點:可以給表加,也可以給行數據加,其特點為: 給目標數據加上share鎖之后允許其他事務繼續對該數 據加share鎖,不允許其他事務對該數據加排它鎖;通常讀取數據時使用 排他鎖/獨占鎖:也叫X鎖 特點:給數據加排它鎖,不允許其他事務繼續給該數據加排它鎖,同時不允許其他事務給該行數據加共享 鎖,適用于寫操作在數據庫中,經常執行讀寫操作為:
select…
insert…
delete…
pdate…
增刪改操作默認給操作的行數據加排它鎖
select操作默認不加任何鎖
如何在查詢時加共享鎖/排它鎖
select …lock in share mode; //查詢加共享鎖
select…for update; //查詢加排它鎖
select…from …where like ‘’ --表鎖
mysql的存儲引擎:
mysql5.5開始存儲引擎變成InnoDB,特點:支持行鎖
悲觀鎖和樂觀鎖
是兩種思想
悲觀鎖:
當多事務/多線程并發執行時,事務總是悲觀的認為,在自己訪問數據期間,其他事務一定會并發執行,此時會產生線程 安全問題,所以為了保證線程安全,這個事務在訪問數據時,立即給數據加鎖,從而保證線程安全. 特點:可以保證線程安全,但是并發執行效率低下 synchronized 排它鎖都是悲觀鎖的應用樂觀鎖:
在多線程/多事務并發執行中,某個事務總是樂觀的認為,在自己執行期間,沒有其他事務與之并發,認為不會產生線程 安全問題,所以不會給數據加鎖;但是確實存在其他事務與之并發執行的情況,確實存在線程安全問題,為了保證線程 安全,通過版本號機制或CAS來保證線程安全.CAS:compare and swap 比較并交換事務
什么是事務
事務是數據庫中執行操作的最小執行單元,不可再分,要么全都執行成功,要么全都執行失敗。事務的四大特性
原子性 一致性 隔離性 持久性數據庫中事務自動提交默認開啟
查看事務的自動提交是否開啟: show variables like 'autocommit' on off 如何關閉事務自動提交: set autocommit=off; 事務管理: 開啟事務: `begin` 提交事務: `commit` 回滾事務: `rollback`對數據庫的增刪改操作默認開啟事務,而select不涉及事務
當業務方法涉及到多步增刪改操作時,且想要他們保證要成功全成功,但凡有一個操作失敗,則整個操作應該全部失 敗,此時就應該為這個業務方法開啟事務管理。
死鎖
數據庫中出現死鎖,數據庫是如何解決的?
clientA: 1. setautocommit=off 2. begin; 3. update student set sname=xx where sno=1 4. delete from course where cno=1 clientB: 1. setautocommit=off 2. begin; 3. update course set..where cno=1 4. delete from student where sno=1 mariadb對死鎖的處理:檢測到死鎖后,讓一端的事務回滾,并提示DeadLock,讓另一端的事務執行成功.視圖 --View-- 筆試題 創建視圖
什么是視圖
視圖是虛擬表,用于展示結果集,其中并不保存數據,其數據來源于真實表中.視圖實質上是用于封裝sql的,后續若想 再次執行相同的sql,直接調用視圖名稱即可.場景:在數據庫中若要多次展示同樣的數據,其數據來源于4表,一樣的sql寫多次,此時出現了sql重復問題 數據庫如何解決這個問題? 將上述的sql封裝起來,給這個sql起一個名字,后續若想再次執行改sql,直接調用名字即可操作視圖
創建視圖
create view view_name as select....... create view view_name(col1,col2,col3,col4) as select......調用視圖 :
因為視圖是虛擬表,所以對視圖的操作和對表的操作是一樣的
select ...from table_name select ...from view_name desc table_name; desc view_name;刪除視圖
drop table table_name drop view view_name視圖注意事項:
1. 視圖實質上是對sql的封裝,而不是對結果集的封裝,視圖的存在并不是用于提高查詢效率的,效率不會提高 2. 視圖的存在是用于查詢的,而不是用于對數據進行寫操作,所以不應該對視圖執行update操作,但是數據庫語法 上允許對視圖執行update操作,但是不一定成功- 視圖來源于單表 - - 修改 -- 成功 - - 刪除 -- 成功 - - 增加 -- 成功- 視圖來源于多表-- 修改1. 修改一張表的字段 -- 成功 2. 同時修改2表的字段 -- 失敗-- 刪除 -- 失敗 -- 添加 -- 失敗 3. 因為視圖中并不保存數據,其數據來源于真實表中,所以真實表中的數據發生改變,視圖中的數據一定會隨之改變事務隔離級別 – 面試
4種
read uncommitted 讀未提交 -- RU read committed 讀已提交 -- RC repeatable read 可重復讀 --RR serializable 可串行化讀未提交
特點:事務可以讀取到其他事務未提交/未回滾前的數據,會產生臟讀 什么是臟讀:由于事務讀取到了其他事務未提交/未回滾前的數據,導致讀取的數據最終是不存在的,這個現象就叫做 臟讀.讀已提交
特點:事務只能讀取到其他事務提交/回滾后的數據,解決了臟讀問題,但是會產生不可重復讀問題. 什么是不可重復讀:在事務A執行期間,其他事務對事務A訪問的數據進行修改操作,導致事務A中前后兩次讀取相同的 數據的結果是不一致的.這個現象就叫做不可重復讀可重復讀
解決了不可重復讀問題,產生了新的問題 -- 幻讀 什么是幻讀: 在事務A訪問數據期間,其他事務執行了插入操作,導致事務A前后兩次讀取到的數據總量不一致,這個 現象就叫做幻讀.可串行化
解決了幻讀問題,實現了多事務并發執行同步效果,所以這個隔離級別的并發執行效率是最低下的四種隔離級別由低到高
讀未提交-->讀已提交-->可重復讀-->可串行化四種隔離級別可能產生的問題
數據庫默認的隔離級別
oracle和sql server 默認的隔離級別為 讀已提交 mysql的 默認隔離級別為 -- 可重復讀mysql默認的隔離級別可重復讀是如何實現的?
存儲引擎為Innodb的mysql,其隔離級別可重復讀的實現是通過MVCC實現的MVCC(Multi-Version Concurrency Control)- 多版本并發控制
多版本并發控制解決了并發安全問題,且并發執行效率高很多. MVCC的實現由三部分配合實現: 1. undolog 2. mysql中的表里邊每個表都有隱藏的三個字段 3. ReadView隱藏字段
row_id -- Innodb存儲引擎提供的隱藏主鍵 -- 當表中沒有主鍵時自動生成 -- 隱藏主鍵 DB_trx_id -- 事務的id -- 該列中保存的id值為最后操作該數據的事務id DB_roll_ptr -- 數據回滾指針,保存要回滾到的數據的地址ReadView
事務執行操作時,會生成當前事務的ReadView,ReadView保存當前事務之前活躍的所有事務id ReadView有四個字段: m_ids: 截止到當前事務id之前,所有活躍的事務id min_trx_id: 記錄以上活躍事務id中的最小值 max_trx_id: 保存當前事務結束后應分配的下一個id值 creator_trx_id: 保存創建ReadView的當前事務id三者如何配合實現mysql的隔離級別
總結
- 上一篇: 【蓝桥杯Web】第十四届蓝桥杯(Web
- 下一篇: caffe+cuda6.5+cudnn7