深入淺出MySQL事務處理和鎖機制

2021-09-08 17:55:58 字數 3395 閱讀 8371

1.      事務處理和併發性

1.1.        基礎知識和相關概念

1 )全部的表型別都可以使用鎖,但是只有 innodb 和 bdb 才有內建的事務功能。

2 )使用 begin 開始事務,使用 commit 結束事務,中間可以使用 rollback 回滾事務。

3 )在預設情況下, innodb 表支援一致讀。

sql 標準中定義了 4 個隔離級別: read uncommited , read commited , repeatable read , serializable 。

read uncommited 即髒讀,乙個事務修改了一行,另乙個事務也可以讀到該行。

如果第乙個事務執行了回滾,那麼第二個事務讀取的就是從來沒有正式出現過的值。 ?

read commited 即一致讀,試圖通過只讀取提交的值的方式來解決髒讀的問題,但是這又引起了不可重複讀取的問題。

乙個事務執行乙個查詢,讀取了大量的資料行。在它結束讀取之前,另乙個事務可能完成了對資料行的更改。當第乙個事務試圖再次執行同乙個查詢,伺服器就會返回不同的結果。

repeatable read 即可重複讀,在乙個事務對資料行執行讀取或寫入操作時鎖定了這些資料行。

但是這種方式又引發了幻想讀的問題。

因為只能鎖定讀取或寫入的行,不能阻止另乙個事務插入資料,後期執行同樣的查詢會產生更多的結果。

serializable 模式中,事務被強制為依次執行。這是 sql 標準建議的預設行為。

4 )如果多個事務更新了同一行,就可以通過回滾其中乙個事務來解除死鎖。

5 ) mysql 允許利用 set transaction 來設定隔離級別。

6 )事務只用於 insert 和 update 語句來更新資料表,不能用於對錶結構的更改。執行一條更改表結構或 begin 則會立即提交當前的事務。

7 )所有表型別都支援表級鎖,但是 myisam 只支援表級鎖。

8 )有兩種型別的表級鎖:讀鎖和寫鎖。

讀鎖是共享鎖,支援併發讀,寫操作被鎖。

寫鎖是獨佔鎖,上鎖期間其他執行緒不能讀表或寫表。

8 )如果要支援併發讀寫,建議採用 innodb 表,因為它是採用行級鎖,可以獲得更多的更新效能。

9 )很多時候,可以通過經驗來評估什麼樣的鎖對應用程式更合適,不過通常很難說乙個鎖比別的更好,這全都要依據應用程式來決定,不同的地方可能需要不同的 鎖。當前 mysql 已經支援 isam, myisam, memory (heap) 型別表的表級鎖了, bdb 表支援頁級鎖, innodb 表支援行級鎖。

10 ) mysql 的表級鎖都是寫鎖優先,而且是採用排隊機制,這樣不會出現死鎖的情況。對於 innodb 和 bdb 儲存引擎來說,是可能產生死鎖的。這是因為 innodb 會自動捕獲行鎖, bdb 會在執行 sql 語句時捕獲頁鎖的,而不是在事務的開始就這麼做。

1.2.        不同鎖的優缺點及選擇

行級鎖的優點及選擇 :

1 )在很多執行緒請求不同記錄時減少衝突鎖。

2 )事務回滾時減少改變資料。

3 )使長時間對單獨的一行記錄加鎖成為可能。

行級鎖的缺點 :

1 )比頁級鎖和表級鎖消耗更多的記憶體。

2 )當在大量表中使用時,比頁級鎖和表級鎖更慢,因為他需要請求更多的所資源。

3 )當需要頻繁對大部分資料做 group by 操作或者需要頻繁掃瞄整個表時,就明顯的比其它鎖更糟糕。

4 )使用更高層的鎖的話,就能更方便的支援各種不同的型別應用程式,因為這種鎖的開銷比行級鎖小多了。

5 )可以用應用程式級鎖來代替行級鎖,例如 mysql 中的 get_lock() 和 release_lock() 。但它們是勸告鎖(原文: these are advisory locks ),因此只能用於安全可信的應用程式中。

6 )對於 innodb 和 bdb 表, mysql 只有在指定用 lock tables 鎖表時才使用表級鎖。在這兩種表中,建議最好不要使用 lock tables ,因為 innodb 自動採用行級鎖, bdb 用頁級鎖來保證事務的隔離。

表鎖的優點及選擇:

1 )很多操作都是讀表。

2 )在嚴格條件的索引上讀取和更新,當更新或者刪除可以用單獨的索引來讀取得到時: update tbl_name set column=value where unique_key_col=key_value;delete from tbl_name where unique_key_col=key_value;

3 ) select 和 insert 語句併發的執行,但是只有很少的 update 和 delete 語句。

4 )很多的掃瞄表和對全表的 group by 操作,但是沒有任何寫表。

表鎖的缺點:

1 )乙個客戶端提交了乙個需要長時間執行的 select 操作。

2 )其他客戶端對同乙個表提交了 update 操作,這個客戶端就要等到 select 完成了才能開始執行。

3 )其他客戶端也對同乙個表提交了 select 請求。由於 update 的優先順序高於 select ,所以 select 就會先等到 update 完成了之後才開始執行,它也在等待第乙個 select 操作。

1.3.        如何避免鎖的資源競爭

1 )讓 select 速度盡量快,這可能需要建立一些摘要表。

2 )啟動 mysqld 時使用引數 --low-priority-updates 。這就會讓更新操作的優先順序低於 select 。

這種情況下,在上面的假設中,第二個 select 就會在 insert 之前執行了,而且也無需等待第乙個 select 了。

3 )可以執行 set low_priority_updates=1 命令,指定所有的更新操作都放到乙個指定的鏈結中去完成。

4 )用 low_priority 屬性來降低 insert , update , delete 的優先順序。

5 )用 high_priority 來提高 select 語句的優先順序。

6 )從 mysql 3.23.7 開始,可以在啟動 mysqld 時指定系統變數 max_write_lock_count 為乙個比較低的值,它能強制臨時地提高表的插入數達到乙個特定值後的所有 select 操作的優先順序。它允許在 write 鎖達到一定數量後有 read 鎖。

7 )當 insert 和 select 一起使用出現問題時,可以轉而採用 myisam 表,它支援併發的 select 和 insert 操作。

8 )當在同乙個表上同時有插入和刪除操作時, insert delayed 可能會很有用。

9 )當 select 和 delete 一起使用出現問題時, delete 的 limit 引數可能會很有用。

10 )執行 select 時使用 sql_buffer_result 有助於減短鎖表的持續時間。

11 )可以修改源** `mysys/thr_lock.c' ,只用乙個所佇列。這種情況下,寫鎖和讀鎖的優先順序就一樣了,這對一些應用可能有幫助。

深入淺出mysql事務處理和鎖機制

1.事務處理和併發性 1.1.基礎知識和相關概念 1 全部的表型別都可以使用鎖,但是只有innodb和bdb才有內建的事務功能。2 使用begin開始事務,使用commit結束事務,中間可以使用rollback回滾事務。3 在預設情況下,innodb表支援一致讀。sql標準中定義了4個隔離級別 re...

深入淺出mysql事務處理和鎖機制

1.事務處理和併發性 1.1.基礎知識和相關概念 1 全部的表型別都可以使用鎖,但是只有innodb和bdb才有內建的事務功能。2 使用begin開始事務,使用commit結束事務,中間可以使用rollback回滾事務。3 在預設情況下,innodb表支援一致讀。sql標準中定義了4個隔離級別 re...

mysql事務處理和鎖機制

1.3.如何避免鎖的資源競爭 1 讓 select 速度盡量快,這可能需要建立一些摘要表。2 啟動 mysqld 時使用引數 low priority updates 這就會讓更新操作的優先順序低於 select 這種情況下,在上面的假設中,第二個 select 就會在 insert 之前執行了,而...