SpringBoot異步任務(wù)實(shí)現(xiàn)下單校驗(yàn)庫存的項(xiàng)目實(shí)踐
??前言
在開發(fā)中,異步任務(wù)應(yīng)用的場(chǎng)景非常的廣泛,本文章以下單時(shí)校驗(yàn)庫存為例來看看SpringBoot中異步任務(wù)的使用。使用異步任務(wù)可以提高系統(tǒng)的響應(yīng)性能,提高系統(tǒng)的并發(fā)能力,改善用戶體驗(yàn),減少資源的浪費(fèi),提高系統(tǒng)的可擴(kuò)展性。
??思維導(dǎo)圖
??流程圖
??必不可少的注解
@EnableAsync
:用于標(biāo)識(shí)啟動(dòng)類,開啟異步任務(wù)。@Component
:標(biāo)識(shí)異步任務(wù)類。@Async
:標(biāo)識(shí)定時(shí)任務(wù)方法。
??獲取異步結(jié)果的API
方法 | 描述 |
---|---|
boolean cancel(boolean mayInterruptIfRunning) | 取消異步任務(wù)的執(zhí)行。 |
boolean isCancelled() | 判斷異步任務(wù)是否被取消。 |
boolean isDone() | 判斷異步任務(wù)是否已經(jīng)完成。 |
V get() throws InterruptedException, ExecutionException | 獲取異步任務(wù)的結(jié)果。 |
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException | 在指定的時(shí)間內(nèi)獲取異步任務(wù)的結(jié)果。如果超時(shí),會(huì)拋出TimeoutException 。 |
??實(shí)現(xiàn)步驟
數(shù)據(jù)準(zhǔn)備
創(chuàng)建數(shù)據(jù)庫表,并插入示例數(shù)據(jù)
CREATE TABLE product ( id INT PRIMARY KEY, name VARCHAR(100), price DECIMAL(10,2), stock INT ); INSERT INTO product (id, name, price, stock) VALUES (1, '蘋果13', 10.99, 50), (2, '小米10', 19.99, 100), (3, '華為mate20', 5.99, 20);
實(shí)體類
public class Product { private Integer id; private String name; private BigDecimal price; private Integer stock; }
啟動(dòng)類開啟異步任務(wù)
添加@EnableAsync開啟異步任務(wù)。
@SpringBootApplication @MapperScan("com.shoanjen.redis.mapper") @EnableCaching @EnableScheduling @EnableAsync public class RedisApplication { public static void main(String[] args) { SpringApplication.run(RedisApplication.class, args); } }
異步任務(wù)方法
在異步任務(wù)方法上添加@Async注解。
方法邏輯:
- 根據(jù)商品id查詢數(shù)據(jù)庫是否存在當(dāng)前商品
- 若商品不存在、或者商品當(dāng)前庫存小于購買量quantity,返回false。
- 若商品存在,進(jìn)行模擬下單操作。更新庫存的數(shù)量。
- 當(dāng)然還有查詢余額的邏輯,我這里沒有寫,跟查詢庫存類似。
優(yōu)點(diǎn):通過異步任務(wù)實(shí)現(xiàn)下單時(shí)查詢庫存以及余額,可以很大的提高性能。
@Component public class ValidateTask { @Autowired private ProductMapper productMapper; //校驗(yàn)庫存功能 @Async public Future<Boolean> validateStock(int productId, int quantity){ //查詢數(shù)據(jù)庫中的商品 Product product=productMapper.selectProductById(productId); //商品庫存校驗(yàn) if (product==null || product.getStock()<quantity){ return new AsyncResult<>(false); }else { //模擬下單操作 product.setStock(product.getStock()-quantity); //這里就演示訂單表保存數(shù)據(jù)了,直接更新庫存 productMapper.updateProduct(product); return new AsyncResult<>(true); } } }
Controller層
方法邏輯:
- 調(diào)用異步任務(wù)。
- 設(shè)置flag標(biāo)記。
- 判斷異步任務(wù)是否完成。
- 如果flag為true,則下單成功,否則失敗。
@RestController @RequestMapping("/api/v1/product") public class ProductController { @Autowired private ValidateTask validateTask; //productId-商品id,quantity-購買數(shù)量 @RequestMapping("order") public JsonData order(@RequestParam int productId,@RequestParam int quantity) throws ExecutionException, InterruptedException { //調(diào)用異步任務(wù) Future<Boolean> validateResult=validateTask.validateStock(productId,quantity); Boolean flag=false; //判斷異步任務(wù)是否完成 if (validateResult.isDone()){ try { flag=validateResult.get(); } catch (Exception e) { flag=false; } } if (flag){ return JsonData.buildSuccess("下單成功"); }else { return JsonData.buildError("下單失敗,庫存不足"); } }
ProductMapper.xml
<mapper namespace="com.shoanjen.redis.mapper.ProductMapper"> <select id="selectProductById" resultType="com.shoanjen.redis.model.Product"> select * from product where id=#{productId} </select> <update id="updateProduct" parameterType="com.shoanjen.redis.model.Product"> update product set name=#{product.name},price=#{product.price},stock=#{product.stock} where id=#{product.id} </update> </mapper>
效果測(cè)試
下單成功測(cè)試
庫存不足測(cè)試
??寫在最后
有關(guān)于SpringBoot異步任務(wù)實(shí)現(xiàn)下單校驗(yàn)庫存的實(shí)戰(zhàn)到此就結(jié)束了,更多相關(guān)SpringBoot 下單校驗(yàn)庫存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Dubbo在Spring和Spring Boot中的使用詳解
這篇文章主要介紹了Dubbo在Spring和Spring Boot中的使用詳解,需要的朋友可以參考下2017-10-10js判斷是否是移動(dòng)設(shè)備登陸網(wǎng)頁的簡(jiǎn)單方法
這篇文章主要介紹了js判斷是否是移動(dòng)設(shè)備登陸網(wǎng)頁的簡(jiǎn)單方法,需要的朋友可以參考下2014-02-02Spring Boot優(yōu)化后啟動(dòng)速度快到飛起技巧示例
這篇文章主要為大家介紹了Spring Boot優(yōu)化后啟動(dòng)速度快到飛起的技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Intellij IDEA導(dǎo)入JAVA項(xiàng)目并啟動(dòng)(圖文教程)
這篇文章主要介紹了Intellij IDEA導(dǎo)入JAVA項(xiàng)目并啟動(dòng),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08Spring觀察者模式之事件發(fā)布訂閱實(shí)現(xiàn)和源碼詳解
這篇文章主要介紹了Spring觀察者模式之事件發(fā)布訂閱實(shí)現(xiàn)和源碼詳解,Spring認(rèn)為發(fā)布訂閱主題,其實(shí)可以理解為事件驅(qū)動(dòng)的編碼,先來實(shí)現(xiàn)以下Spring容器中的事件發(fā)布訂閱,需要的朋友可以參考下2024-01-01SpringAOP核心對(duì)象的創(chuàng)建圖解
這篇文章主要介紹了SpringAOP核心對(duì)象的創(chuàng)建詳解,通過使用AOP,我們可以將橫切關(guān)注點(diǎn)(如日志記錄、性能監(jiān)控、事務(wù)管理等)從業(yè)務(wù)邏輯中分離出來,使得代碼更加模塊化、可維護(hù)性更高,需要的朋友可以參考下2023-10-10實(shí)例詳解java Struts2的配置與簡(jiǎn)單案例
這篇文章主要介紹了java Struts2的配置與簡(jiǎn)單案例,需要的朋友可以參考下2017-04-04