【MySQL】事物認識
概念

本事上是使用行級鎖實現(排它鎖,共享鎖)
事物處理可以確保非事物性單元內的所有操作都成功完成,否則不會永遠更新面向數據的資源。通過將這一組相關操作組合成為一個要么全部成功要么全部失敗的的單元,可以簡化錯誤恢復病史應用程序更加可靠。一個邏輯單元要成為事物,必須滿足所謂的acid屬性
屬性
原子性
對于數據修改,要么全部都執行,要么全都不執行
隔離性
在所有的操作沒有執行完畢之前,其他回話不能夠看到中間改變的過程
我們打開倆個查詢器,然后同時對一個表進行數據計算總值。可以看到起初的數據是一樣的
然后我們開啟事物,執行一個添加的操作,并且再次查詢總數
然后我們在到左邊執行一下語句查看有多少條數據
然后右邊查詢提交事物,這就是事物的隔離性
一致性
事物發生前和發生后,根據數據的規則,總額應該匹配
持久性
事物一旦被提交,其結果就是永久性的,系統崩潰也不會影響
執行過程
因為Mysql5之后通常的默認存儲引擎是InnoDB所以,以InnoDB為例講解實現過程
Mysql在進行事務處理的時候使用的是日志現行的方式來保證事務可快速和持久運行的,也就是在寫數據庫前,需要先寫日志。當開始一個事務時,會記錄該事物的一個LSN日志序列號;當執行事務時,會往InnoDB_Log_Buffer 日志緩沖區里插入事務日志(redo log);當事務提交時,會將日志緩存區里的事務日志刷入磁盤。這個動作主要是由innodb_flush_log_at_trx_commit這個參數控制的。
發出commit動作時。已經說明過,commit發出后是否刷日志由變量 innodb_flush_log_at_trx_commit 控制。
每秒刷一次。這個刷日志的頻率由變量 innodb_flush_log_at_timeout 值決定,默認是1秒。要注意,這個刷日志頻率和commit動作無關。
當log buffer中已經使用的內存超過一半時。
當有checkpoint時,checkpoint在一定程度上代表了刷到磁盤時日志所處的LSN位置。
可以通過命令
show engine innodb status\G;
Log sequence number 8619676075 (表示當前的LSN日志序列號)
Log flushed up to 8619676075 (表示刷新到事物日志的LSN日志序列號)
Last checkpoint at 8619676075 (表示刷新到磁盤的LSN日志序列號)
除了記錄事務日志意外,數據庫還會記錄一定量的撤銷日志(undo log), undo與redo正好相反,在對數據進行修改時,由于某種原因失敗了,或者人為執行了rollback回滾語句,就可以利用這些撤銷日志將數據回滾到修改之前的樣子。redo日志保存在ib_logfile0/1/2里,而undo日志保存在ibdata1里,在MySQL5.6里還可以把undo日志單拆分出去。
對于事務的建議
innodb存儲引擎由于實現了行幾所,顆粒更小,實現更復雜。但是innodb行鎖在并發性能上遠遠要高于表鎖頁鎖。在使用方面可以盡量做到以下幾點;
控制事務大小,減少鎖定的資源量和鎖定時間長度。
人所有的數據檢索都通過索引來完成,從而避免因為無法通過索引加鎖而升級為表鎖。
減少基于范圍的數據檢索過濾條件,避免因為間隙鎖帶來的負面影響而鎖定了不該鎖定的數據。
在業務條件允許下,盡量使用較低隔離級別的事務隔離。減少隔離級別帶來的附加成本。
河里使用索引,讓innodb在索引上面加鎖的時候更加準確。
在應用中盡可能做到訪問的順序執行
如果容易死鎖,就可以考慮使用表鎖來減少死鎖的概率
MySQL
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。