共享鎖:又稱爲讀鎖,簡稱S鎖,顧名思義,共享鎖就是多個事務對於同一數據能夠共享一把鎖,都能訪問到數據,可是隻能讀不能修改。mysql
排他鎖:又稱爲寫鎖,簡稱X鎖,顧名思義,排他鎖就是不能與其餘所並存,如一個事務獲取了一個數據行的排他鎖,其餘事務就不能再獲取該行的其餘鎖,包括共享鎖和排他鎖,可是獲取排他鎖的事務是能夠對數據就行讀取和修改。sql
mysql InnoDB引擎默認的修改數據語句,update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型,blog
若是加排他鎖能夠使用select ...for update語句,加共享鎖能夠使用select ... lock in share mode語句。索引
因此加過排他鎖的數據行在其餘事務種是不能修改數據的,也不能經過for update和lock in share mode鎖的方式查詢數據,事務
但能夠直接經過select ...from...查詢數據,由於普通查詢沒有任何鎖機制。get
begin; select * from goods where id = 1 for update; update goods set stock = stock - 1 where id = 1; commit;
表鎖和行鎖it
InnoDB行鎖是經過給索引上的索引項加鎖來實現的,只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然,InnoDB將使用表鎖。class
悲觀鎖:date
/* 更新庫存(使用悲觀鎖) * @param productId * @return */ public boolean updateStock(Long productId){ //先鎖定商品庫存記錄 ProductStock product = query("SELECT * FROM tb_product_stock WHERE product_id=#{productId} FOR UPDATE", productId); if (product.getNumber() > 0) { int updateCnt = update("UPDATE tb_product_stock SET number=number-1 WHERE product_id=#{productId}", productId); if(updateCnt > 0){ //更新庫存成功 return true; } } return false; }
樂觀鎖:select
/** * 下單減庫存 * @param productId * @return */ public boolean updateStock(Long productId){ int updateCnt = 0; while (updateCnt == 0) { ProductStock product = query("SELECT * FROM tb_product_stock WHERE product_id=#{productId}", productId); if (product.getNumber() > 0) { updateCnt = update("UPDATE tb_product_stock SET number=number-1 WHERE product_id=#{productId} AND number=#{number}", productId, product.getNumber()); if(updateCnt > 0){ //更新庫存成功 return true; } } else { //賣完啦 return false; } } return false; }