樂優商城專案總結day 19

2021-09-23 08:11:07 字數 3273 閱讀 5642

在建立訂單時涉及到了庫存的修改,在高併發的情況下減庫存應該加鎖。考慮到到分布式的問題,jvm自帶的鎖只能鎖住本機,因此此處使用mysql自帶的事務與行鎖解決。

dao層如下:

@repository

@update("update tb_stock set stock = stock - # where sku_id = # and stock >= #")

int decreasestock(@param("id") long id, @param("num") integer num);

}

我的理解是:在減庫存中,a使用者進行了減庫存的操作,那麼在這個a事務內會對該id的商品加上行鎖,在a事務提交之前,

假設此時b使用者也同時對該id的商品進行了減庫存的操作,那麼在b事務裡對該id商品的更新是會被阻塞住的,直到a事務成功提交後才會釋放行鎖,b事務才能繼續對該商品的庫存進行修改。

後面的stock>=num條件主要是為了保證此次庫存修改之後庫存數必須大於等於0,否則庫存數不足。

有的人會疑惑 update 會導致行鎖,如果程式掛了,事務沒有提交,其他事務豈不是會一直堵塞在那裡,阻礙別的update語句。 經過測試程式掛了,mysql會自己自動放棄鎖,使別的update語句順利執行。

查閱了網上很多資料,說這裡用到了樂觀鎖,但是我搞半天也沒看出來。。。。希望大神能指點下。。

行鎖公升級表鎖

避免行鎖公升級為表鎖,影響併發效能,以下為常見的情況:

顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。它指的是對資料被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改資料)。

上面實現的減庫存應該也是基於悲觀鎖的。

顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,像資料庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。

文章2兩種鎖各有優缺點,不可認為一種好於另一種,像樂觀鎖適用於寫比較少的情況下,即衝突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生衝突,上層應用會不斷的進行retry,這樣反倒是降低了效能,所以這種情況下用悲觀鎖就比較合適。

在分頁查詢訂單時,因為查詢的條件是動態的,並且涉及到了多表查詢,因此單獨使用@select註解以及@results註解或者selectbyexample()都不能解決既要多表查詢又要動態查詢的要求。因此可以使用xml配置檔案的方式或者用@selectprovider註解以及@results註解來解決,本專案使用第二種方式。

@selectprovider是用來動態生成sql的,其用法如下:

type引數為動態生成sql類的class物件,method引數為具體生成哪條動態sql對應的方法名稱,在這個類的方法中根據條件生成具體的sql。

@results是在單錶或多表查詢之後對結果的對映,可以進行一對

一、一對多的對映,類似於xml檔案中的作用。

id引數和xml中的id作用差不多,給該對映加上id便於後面的復用。

result引數為乙個陣列,裡面需要傳入多個@result

每個@result實際上對應著資料庫查詢結果的列與實體類欄位的對映,如果欄位的值不是直接對映,那麼需要使用one或者many來進行進一步的查詢對映,one為一對一時的對映,many為一對多時的對映。

select引數中傳入對應包下的查詢方法,通過@result中的column傳入該方法所需要的引數值,返回的結果將會賦給對應的property

綜合示例如下:

@repository

@selectprovider(type = orderprovider.class, method = "queryorderbypage")

@results()

listqueryorderbypage(@param("orderstatus") integer orderstatus, @param("userid") long userid);

}

@repository

@select("select * from tb_order_detail where order_id = #")

listquerybyorderid(@param("orderid") long orderid);

}

public class orderprovider ");

if(orderstatus != null) ");

}sql.order_by("create_time desc");

return sql.tostring();}}

mybatis:

configuration:

樂優商城專案總結day 12

spring data 的強大之處,就在於你不用寫任何dao處理,自動根據方法名或類的資訊進行crud操作。只要你定義乙個介面,然後繼承repository提供的一些子介面,就能具備各種基本的crud功能。除此之外,還能通過search querybuilder var1 或search query...

day19 學習總結

今天學習了陣列的使用和多維陣列。下面是知識點 package com.liangwenwei.陣列 public class 陣列的使用 列印全部陣列元素 for int i 0 i arrays.length i system.out.println 列印全部陣列元素 for int array ...

樂優商城專案學習

樂優 專案是乙個全品類的電商購物 感覺就像是按著京東來做的,並且發現華為 也是這樣設計,看到商品詳情,有那麼一丟丟的親切感。這個專案是基於微服務架構,如果沒做過微服務開發或者想對電商專案有所了解,拿來玩玩還是不錯的。既然花了時間在上面,就應該有自己能學習到東西,哪怕是很少的收穫,畢竟不積跬步無以至千...