mysql鎖機制

共享鎖:又稱爲讀鎖,簡稱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;
    }
相關文章
相關標籤/搜索