標籤:共用 版本 mysq 行修改 取值 失敗 9.png blog 另一個
通常鎖分為悲觀鎖和樂觀鎖,所謂悲觀鎖就是處處提防著其人操作,生怕別人和自己搶資源,所以一上來就加鎖了;而樂觀鎖就是老是樂天派覺得沒人會和自己搶資源,只要按照規則來就沒事,是自己通過資料庫設定一個資料庫欄位來類比鎖機制,是一個君子協議,樂觀的認為大家都是君子都會遵守。悲觀鎖分讀鎖和寫鎖,無論是讀鎖還是寫鎖,都不影響查詢,查詢大家都可以執行而且擷取到結果,兩把鎖的區別就是讀鎖可以共用鎖定可以同時多人持有鎖,大家都拿著號等著隨時更新資料的權利,誰手快誰先更新,但是寫鎖就只能一次只有一人拿著號,只有等目前使用者操作完全完成了,其他人才可以拿到號進行更新操作,就像排隊進行一樣,鎖還分行級鎖和整個表的鎖,行級鎖只是鎖當前id指定的行,而整表鎖就是直接鎖在表上,沒有where條件限制,在mysql中具體文法如下:
讀鎖(也叫共用鎖定)就是查詢的時候不希望資料被其他人修改,這時可以設定讀的共用模式鎖,大家都可以讀取,讀取資料不受限制,都可以持有讀取共用鎖定,但是如果其中一個人沒有提交事務,另一個人就不能修改當前鎖定的表,當然如果沒有其他人同時持有讀取鎖,只有自己持有,那麼自己是可以修改資料的,不過只要有兩人同時持有讀取鎖,那麼一方就不能隨意修改資料,讀取共用鎖定文法是在事務中 select * from 表名 lock in share model
寫鎖(也叫獨佔鎖定),寫鎖不能共用,只要有人加了寫鎖,那麼其他人就不能做加鎖操作,哪怕是加共用鎖定,反正當前行或表資料的鎖只能一個人持有這把鎖,其他人不能同時持有,其他人想修改持有寫鎖,只能等上一個人提交事務後才能擷取到寫鎖,不然就得一直等待,此時就算不是去擷取鎖,熱只是想修改資料也得等待上一個人事務提交,但是如果只是查詢操作還是不受限制的
如果一直等不到其他人事務提交,那麼就有可能更新操作逾時,會報錯,但是資料沒問題,只是更新失敗,這時代碼加異常捕獲處理即可,在mysql中sql加悲觀鎖是通過lack關鍵字,但是在Hibernate又該如何添加悲觀鎖呢?就是調用Hibernate方法時通過指定參數lockOptions這個枚舉來讓Hibernate決定產生sql時如何添加lock關鍵字,如下:
hibernate產生的是行級鎖,有where條件限制,只在當前行上加鎖,其他行並沒有加鎖,其他人可以對其他沒有加鎖的行資料進行修改或加鎖,這樣細粒度劃分可以提高mysql的執行效率,不需要一鎖就鎖整張表,搞的大家都得等,就像一人上廁所,本來只要佔一個坑就行,卻偏偏對整個廁所來個包場,顯然就不合理了。
=====================================================
樂觀鎖:其實樂觀鎖不是資料庫本身提供的鎖機制,是人為類比實現的,如添加一個欄位如version,其取值為預設遞增的整數,預設值為1,只要有一個人進來就把值在先前基礎上加1,不用等待,但是大家都得遵守一個約定就是提交之前先去資料庫判斷一下version版本是否和自己目前的版本一致,如果不一致那麼先把資料更新了,保證和資料庫資料一致再進行提交,類似於svn控製版本衝突的解決思路
mysql鎖機制