package com.txc.redisconcurrency.controller;
import com.txc.redisconcurrency.exception.MyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Controller
public class StockController {
@Resource
private RedisTemplate<String,String> redisTemplate;
//查询库存后,修改库存信息
@RequestMapping("/changeStock")
@ResponseBody
public void changeStock(HttpSession session){
//假设每次购买的产品数量为2
int buyCount=2;
//创建操作Redis字符串参数对象
ValueOperations<String,String> opsString=redisTemplate.opsForValue();
//
String lockKey="stock";//需要加锁的key,这个key是自定义的key
String goodsKey="goods:mobile.huawei001";//逆向修改的商品的key
String sessionId=session.getId();//确保加锁和解锁的是同一个人。
//在查询lockKey之前,先给lockKey加锁,然后再查询数据,然后再修改数据,最后解锁
boolean lockResult=false;
try{
lockResult=opsString.setIfAbsent(lockKey,sessionId,30, TimeUnit.SECONDS);
}catch (Exception e){
System.out.println("============加锁失败============");
e.printStackTrace();
}
System.out.println("=======lockResult====="+lockResult);
if(lockResult){
try{
//查询数据
int stockCount=Integer.valueOf(opsString.get(goodsKey));
if (stockCount>=2){//判断库存是否足够
//库存数量减去购买的数量
stockCount=stockCount-buyCount;
System.out.println(lockKey+"===1==="+stockCount);
//将新的库存信息重写写入到redis中
opsString.set(goodsKey,stockCount+"");
}else{
System.out.println("=========库存不足========");
}
}catch(Exception e){
e.printStackTrace();
System.out.println("=========程序异常,请重新操作=========");
}finally {
//释放锁
System.out.println("========锁释放成功=======");
redisTemplate.delete(lockKey);
}
}else{
//key已加锁,稍后重试
throw new MyException();
}
}
/**
* 查询库存后,修改库存信息
* 解决极端情况下,setIfAbsent的并发问题
* @param session
*/
@RequestMapping("/changeStock_upgrad")
@ResponseBody
public void changeStock_upgrad(HttpSession session){
//假设每次购买的产品数量为2
int buyCount=2;
//创建操作Redis字符串参数对象
ValueOperations<String,String> opsString=redisTemplate.opsForValue();
String lockKey="stock";//需要加锁的key,这个key是自定义的key
String goodsKey="goods:mobile.huawei001";//逆向修改的商品的key
boolean lockResult=false;
//生成一个随机的唯一的id
String lockValue= UUID.randomUUID().toString();
try{
//在查询lockKey之前,先给lockKey加锁,然后再查询数据,然后再修改数据,最后解锁
lockResult=opsString.setIfAbsent(lockKey,lockValue,30, TimeUnit.SECONDS);
}catch (Exception e){
System.out.println("============加锁失败============");
e.printStackTrace();
}
System.out.println("=======lockResult====="+lockResult);
if(lockResult){
try{
//判断二次lockValue的值是否相等,解决极端情况下并发问题
String lockValue1=opsString.get(lockKey);
if(lockValue1.equals(lockValue)){
//查询数据
int stockCount=Integer.valueOf(opsString.get(goodsKey));
if (stockCount>=2){//判断库存是否足够
//库存数量减去购买的数量
stockCount=stockCount-buyCount;
System.out.println(lockKey+"===1==="+stockCount);
//将新的库存信息重写写入到redis中
opsString.set(goodsKey,stockCount+"");
}else{
System.out.println("=========库存不足========");
}
}else {
//key已加锁,稍后重试
throw new MyException();
}
}catch(Exception e){
e.printStackTrace();
System.out.println("=========程序异常,请重新操作=========");
}finally {
//释放锁
System.out.println("========锁释放成功=======");
redisTemplate.delete(lockKey);
}
}else{
//key已加锁,稍后重试
throw new MyException();
}
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
springboot整合Redis实现在分布式情况,使用分布式锁解决数据并发的方案,主要使用Redis提供的setIfAbsent方法实现,并且考虑到了setIfAbsent在极端情况下的多实例同时设置一个key成功的情况。 本案例通过实现对库存的查询和修改,实现了在分布式情况下的数据安全操作。保证了数据的一致性。
资源推荐
资源详情
资源评论
收起资源包目录
Redis分布式锁使用+Redis处理数据并发+springboot整合Redis (101个子文件)
StockController.class 4KB
RedisConfig.class 2KB
SpringbootredisdataconcurrencyApplication.class 827B
SpringbootredisdataconcurrencyApplicationTests.class 625B
MyException.class 426B
.gitignore 395B
.gitignore 184B
springbootredisdataconcurrency.iml 10KB
StockController.java 5KB
RedisConfig.java 2KB
SpringbootredisdataconcurrencyApplication.java 377B
SpringbootredisdataconcurrencyApplicationTests.java 249B
MyException.java 208B
uiDesigner.xml 9KB
workspace.xml 3KB
pom.xml 2KB
compiler.xml 881B
jarRepositories.xml 879B
Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_13_5.xml 736B
Maven__io_netty_netty_transport_native_unix_common_4_1_89_Final.xml 726B
Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_7_9.xml 713B
Maven__org_springframework_boot_spring_boot_starter_data_redis_2_7_9.xml 713B
Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml 700B
Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_13_5.xml 695B
Maven__org_springframework_boot_spring_boot_starter_logging_2_7_9.xml 692B
Maven__org_springframework_boot_spring_boot_starter_tomcat_2_7_9.xml 685B
Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_13_5.xml 681B
Maven__org_springframework_boot_spring_boot_autoconfigure_2_7_9.xml 678B
Maven__org_springframework_boot_spring_boot_starter_json_2_7_9.xml 671B
Maven__org_springframework_boot_spring_boot_starter_test_2_7_9.xml 671B
Maven__org_springframework_boot_spring_boot_starter_web_2_7_9.xml 664B
Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_71.xml 660B
Maven__com_fasterxml_jackson_core_jackson_annotations_2_13_5.xml 651B
Maven__org_springframework_spring_context_support_5_3_25.xml 644B
Maven__org_springframework_data_spring_data_keyvalue_2_7_8.xml 643B
Maven__org_springframework_boot_spring_boot_starter_2_7_9.xml 636B
Maven__org_springframework_data_spring_data_commons_2_7_8.xml 636B
Maven__org_junit_platform_junit_platform_commons_1_8_2.xml 633B
Maven__jakarta_activation_jakarta_activation_api_1_2_2.xml 633B
Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml 633B
Maven__com_fasterxml_jackson_core_jackson_databind_2_13_5.xml 630B
Maven__org_junit_platform_junit_platform_engine_1_8_2.xml 626B
Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_71.xml 625B
Maven__org_springframework_data_spring_data_redis_2_7_8.xml 622B
Maven__org_junit_jupiter_junit_jupiter_params_5_8_2.xml 615B
Maven__org_springframework_boot_spring_boot_test_2_7_9.xml 615B
Maven__org_junit_jupiter_junit_jupiter_engine_5_8_2.xml 615B
Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_3.xml 611B
Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_71.xml 611B
Maven__org_springframework_spring_expression_5_3_25.xml 609B
Maven__org_apache_logging_log4j_log4j_to_slf4j_2_17_2.xml 608B
Maven__com_fasterxml_jackson_core_jackson_core_2_13_5.xml 602B
Maven__org_mockito_mockito_junit_jupiter_4_5_1.xml 598B
Maven__org_reactivestreams_reactive_streams_1_0_4.xml 595B
Maven__io_lettuce_lettuce_core_6_1_10_RELEASE.xml 594B
Maven__org_junit_jupiter_junit_jupiter_api_5_8_2.xml 594B
Maven__io_netty_netty_transport_4_1_89_Final.xml 593B
Maven__org_springframework_spring_context_5_3_25.xml 588B
Maven__io_netty_netty_resolver_4_1_89_Final.xml 586B
Maven__net_bytebuddy_byte_buddy_agent_1_12_23.xml 585B
Maven__org_springframework_spring_webmvc_5_3_25.xml 581B
Maven__org_springframework_boot_spring_boot_2_7_9.xml 580B
Maven__io_netty_netty_handler_4_1_89_Final.xml 579B
Maven__ch_qos_logback_logback_classic_1_2_11.xml 575B
Maven__org_springframework_spring_beans_5_3_25.xml 574B
Maven__org_apache_logging_log4j_log4j_api_2_17_2.xml 573B
Maven__io_netty_netty_common_4_1_89_Final.xml 572B
Maven__io_netty_netty_buffer_4_1_89_Final.xml 572B
Maven__org_apiguardian_apiguardian_api_1_1_2.xml 572B
Maven__org_springframework_spring_test_5_3_25.xml 567B
Maven__org_springframework_spring_core_5_3_25.xml 567B
Maven__io_projectreactor_reactor_core_3_4_27.xml 566B
Maven__org_junit_jupiter_junit_jupiter_5_8_2.xml 566B
Maven__io_netty_netty_codec_4_1_89_Final.xml 565B
Maven__org_springframework_spring_aop_5_3_25.xml 560B
Maven__org_springframework_spring_oxm_5_3_25.xml 560B
Maven__org_springframework_spring_web_5_3_25.xml 560B
Maven__org_springframework_spring_jcl_5_3_25.xml 560B
Maven__net_minidev_accessors_smart_2_4_8.xml 556B
Maven__ch_qos_logback_logback_core_1_2_11.xml 554B
Maven__org_springframework_spring_tx_5_3_25.xml 553B
Maven__com_jayway_jsonpath_json_path_2_7_0.xml 546B
Maven__net_bytebuddy_byte_buddy_1_12_23.xml 543B
Maven__org_assertj_assertj_core_3_22_0.xml 542B
Maven__org_skyscreamer_jsonassert_1_5_1.xml 537B
Maven__org_xmlunit_xmlunit_core_2_9_1.xml 535B
Maven__org_mockito_mockito_core_4_5_1.xml 535B
Maven__org_slf4j_jul_to_slf4j_1_7_36.xml 534B
Maven__org_opentest4j_opentest4j_1_2_0.xml 533B
Maven__org_projectlombok_lombok_1_18_26.xml 531B
Maven__net_minidev_json_smart_2_4_8.xml 521B
Maven__org_slf4j_slf4j_api_1_7_36.xml 513B
Maven__org_objenesis_objenesis_3_2.xml 508B
Maven__org_hamcrest_hamcrest_2_2.xml 497B
Maven__org_yaml_snakeyaml_1_30.xml 495B
misc.xml 475B
Maven__org_ow2_asm_asm_9_1.xml 458B
modules.xml 307B
encodings.xml 191B
application.yml 122B
共 101 条
- 1
- 2
资源评论
雾林小妖
- 粉丝: 1w+
- 资源: 90
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功