InnoDB與MyISAM的最大不同有兩點:一是支持事務(TRANSACTION);二是采用了行級鎖,
查看鎖命令:
show status like 'innodb_row_lock%';
鎖分類
-
讀鎖:也叫共享鎖、S鎖,若事務T對資料物件A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S 鎖,這保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改,
-
寫鎖:又稱排他鎖、X鎖,若事務T對資料物件A加上X鎖,事務T可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到T釋放A上的鎖,這保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A,
-
表鎖:操作物件是資料表,Mysql大多數鎖策略都支持(常見mysql innodb),是系統開銷最低但并發性最低的一個鎖策略,事務t對整個表加讀鎖,則其他事務可讀不可寫,若加寫鎖,則其他事務增刪改都不行,
-
行級鎖:操作物件是資料表中的一行,是MVCC技術用的比較多的,但在MYISAM用不了,行級鎖用mysql的儲存引擎實作而不是mysql服務器,但行級鎖對系統開銷較大,處理高并發較好,
MySQL不同的存盤引擎支持不同的鎖機制,
頁級:引擎 BDB,
表級:引擎 MyISAM , 理解為鎖住整個表,可以同時讀,寫不行
行級:引擎 INNODB , 單獨的一行記錄加鎖
-
表級,直接鎖定整張表,在你鎖定期間,其它行程無法對該表進行寫操作,如果你是寫鎖,則其它行程則讀也不允許,開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,并發度最低,
-
行級, 僅對指定的記錄進行加鎖,這樣其它行程還是可以對同一個表中的其它記錄進行操作,開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,并發度也最高,
-
頁級,表級鎖速度快,但沖突多,行級沖突少,但速度慢,所以取了折衷的頁級,一次鎖定相鄰的一組記錄,開銷和加鎖時間界于表鎖和行鎖之間;會出現死鎖;鎖定粒度界于表鎖和行鎖之間,并發度一般
行鎖和表鎖
得出行鎖升級為表鎖的原因之一是: SQL 陳述句中未使用到索引,或者說使用的索引未被資料庫認可(相當于沒有使用索引),
提出行鎖升級為表鎖與 事務的隔離級別 有關,并給出了事例,當然,我同意這個說法,因為事務的隔離性是靠加鎖來實作的,而加鎖勢必會影響并發,
我針對 “普通索引是表鎖” 進行了驗證,結果發現普通索引并不一定會引發表鎖,在普通索引中,是否引發表鎖取決于普通索引的高效程度(當索引欄位重復度高就會變成表鎖),
結論:當“值重復率”低時,甚至接近主鍵或者唯一索引的效果,“普通索引”依然是行鎖;當“值重復率”高時,MySQL 不會把這個“普通索引”當做索引,即造成了一個沒有索引的 SQL,此時引發表鎖,
http://zhoupq.com/MySQL-避免行鎖升級為表鎖——使用高效的索引/
行鎖悲觀鎖的使用
要使用悲觀鎖,我們必須關閉mysql資料庫的自動提交屬性,因為MySQL默認使用autocommit模式,也就是說,當你執行一個更新操作后,MySQL會立刻將結果進行提交,
SELECT ... FOR UPDATE 實作悲觀鎖
show variables like "autocommit";
set autocommit=0;
//0.開始事務
begin;/begin work;/start transaction; (三者選一就可以)
//1.查詢出商品資訊
select status from t_goods where id=1 for update;
//2.根據商品資訊生成訂單
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status為2
update t_goods set status=2;
//4.提交事務
commit;/commit work;
注:需要注意的是,在事務中,只有SELECT … FOR UPDATE 或LOCK IN SHARE MODE 同一筆資料時會等待其它事務結束后才執行,一般SELECT … 則不受此影響,
來自:http://chenzhou123520.iteye.com/blog/1860954
當前讀:特殊的讀操作,插入/更新/洗掉操作,屬于當前讀,處理的都是當前的資料,需要加鎖,
- select * from table where ? lock in share mode;
- select * from table where ? for update;
來自:Innodb中的事務隔離級別和鎖的關系 https://tech.meituan.com/innodb-lock.html
樂觀鎖
hibernate中如何實作樂觀鎖:
前提:在現有表當中增加一個冗余欄位,version版本號, long型別
原理:
1)只有當前版本號》=資料庫表版本號,才能提交
2)提交成功后,版本號version ++
先查詢,更新時帶上查詢條件去更新
來自:http://www.topthink.com/topic/815.html
表鎖
LOCK tables orders read local,order_detail read local;
SELECT SUM(total) FROM orders;
SELECT SUM(subtotal) FROM order_detail;
Unlock tables;
參考資料
MySQL中的鎖(表鎖、行鎖)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/159595.html
標籤:其他
下一篇:jsp登錄驗證
