Springboot使用redisson實現分布式鎖的代碼示例
一、前言
在實際項目中,某些場景下可能需要使用到分布式鎖功能,那么實現分布式鎖有多種方式,常見的如mysql分布式鎖、zookeeper分布式鎖、redis分布式鎖,從效率上講,redis無疑是性能最好的,但也會存在一些問題
1.獲取鎖的線程在執(zhí)行任務的過程中掛掉,來不及釋放鎖,這塊資源將會永遠被鎖?。ㄋ梨i),別的線程再也別想進來,因此我們需要給key加個過期時間,保證這把鎖要在一定時間后自動釋放。
2.高并發(fā)情況下redis分布式鎖永久失效 的問題(一個線程可能刪除了別的線程的鎖)
假設線程 A 可能某些原因執(zhí)行的很慢很慢,到達過期時間都沒執(zhí)行完,這時候鎖過期自動釋放,此時線程 B 得到了鎖;
隨后,線程 A 執(zhí)行完了任務,線程 A 隨之釋放鎖。但這時候線程 B 還沒執(zhí)行完,線程A實際上 刪除的是線程 B加的鎖
解決方法:
可以在 釋放鎖之前做一個判斷,驗證當前的鎖是不是自己加的鎖
3.可能出現并發(fā)情況
當線程 A 執(zhí)行的很慢很慢,到達過期時間都沒執(zhí)行完,這時候鎖過期自動釋放,線程 B得到了鎖。此時就有多個線程在訪問同步代碼塊。
解決方法:我們可以使用redisson實現,內部實現鎖續(xù)期功能。
二、實現
1.在springboot中引入redisson依賴包
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.10.6</version> </dependency>
2.配置redisson,代碼如下:
import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @Configuration public class RedissonConfig { @Bean(destroyMethod = "shutdown") public RedissonClient redisson() throws IOException{ //RedissonClient redisson = Redisson.create(Config.fromYAML(new //ClassPathResource("redisson-single.yml").getInputStream())); Config config = new Config(); config.useSingleServer() .setAddress("redis://192.168.6.52:6379").setPassword("123456") .setRetryInterval(5000) .setTimeout(10000) .setConnectTimeout(10000); return Redisson.create(config); } }
3.我們以商品庫存為例:
import java.util.concurrent.TimeUnit; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.suntree.entity.Price; import com.suntree.mapper.PriceMapper; @Service public class ProductService { @Autowired RedissonClient redissonClient; @Autowired ProductMapper productMapper; @Transactional public String descreaseProduct(String productId,Integer quanlity) { String key="des_product_lock:"+productId; RLock lock=redissonClient.getLock(key); lock.lock(); Product product =productMapper.selectById(productId); if(product ==null) { return "產品未找到"; } String result=""; try { if(product .getQuanlity()==0) { return "當前數量為0,不能再扣了!!"; } product .setQuanlity(product .getQuanlity()-1); productMapper.updateById(product ); result = "當前數量:" + product .getQuanlity(); System.err.println(result); }catch (Exception e) { System.err.println(e.getMessage()); throw new RuntimeException("扣庫存操作失敗了"); }finally { lock.unlock(); } return result; } }
這就是實現分布式鎖常見場景。
4.接著我們可以在controller層調用,我們可以模擬多線程操作,看扣庫存是否會有問題。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.suntree.service.ProductService ; @RestController @RequestMapping("/product") public class ProductController { @Autowired ProductService productService ; @GetMapping("/descrease") public String descreaseProduct() { return productService .descreaseProduct("2020-2020", 200); } }
大家可以自己嘗試下。
到此這篇關于Springboot使用redisson實現分布式鎖的代碼示例的文章就介紹到這了,更多相關Springboot redisson實現分布式鎖內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- 基于SpringBoot+Redis實現分布式鎖
- 如何在SpringBoot中使用Redis實現分布式鎖
- SpringBoot RedisTemplate分布式鎖的項目實戰(zhàn)
- SpringBoot基于Redis的分布式鎖實現過程記錄
- 關于SpringBoot 使用 Redis 分布式鎖解決并發(fā)問題
- SpringBoot整合Redisson實現分布式鎖
- springboot 集成redission 以及分布式鎖的使用詳解
- SpringBoot之使用Redis實現分布式鎖(秒殺系統(tǒng))
- SpringBoot集成redis實現分布式鎖的示例代碼
- 基于springboot實現redis分布式鎖的方法
- Springboot中使用Redis實現分布式鎖的示例代碼
相關文章
ScrollView中嵌入ListView只顯示一條的解決辦法
在ScrollView添加一個ListView會導致listview控件顯示不全,通常只會顯示一條,究竟是什么原因呢?下面腳本之家小編給大家介紹ScrollView中嵌入ListView只顯示一條的解決辦法,感興趣的朋友一起學習吧2016-05-05java項目中常用指標UV?PV?QPS?TPS含義以及統(tǒng)計方法
文章介紹了現代Web應用中性能監(jiān)控和分析的重要性,涵蓋了UV、PV、QPS、TPS等關鍵指標的統(tǒng)計方法,并提供了示例代碼,同時,文章還討論了性能優(yōu)化和瓶頸分析的策略,以及使用Grafana等可視化工具進行監(jiān)控與告警的重要性2025-01-01springBoo3.0集成knife4j4.1.0的詳細教程(swagger3)
這篇文章主要介紹了springBoo3.0集成knife4j4.1.0的詳細教程(swagger3),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07Java編譯錯誤問題:需要class,interface或enum
這篇文章主要介紹了Java編譯錯誤問題:需要class,interface或enum,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02