原理

redis设置一个key和value,如果存在则获取锁失败,不存在则获取锁成功处理业务,业务处理完成后删除这条数据,可以带个失效时间。

代码

public void handleInvoice(SubmitInvoiceRpcReq req) throws Exception {
boolean isAccess = false;
String invoiceKey = String.format(ApiRedisKey.AGENT_WITHDRAW_INVOICE, req.getBaseUserId());
try {
isAccess = redisTemplate.setIfAbsent(invoiceKey, "1", 60);
JlpayAssert.isTrue(isAccess, "正在处理,稍后再试");
//批处理ID(时间戳+用户ID)
String batchNo = System.currentTimeMillis() + String.format("%010d", req.getBaseUserId());
InvoiceVo invoiceVo = new InvoiceVo();
invoiceVo.setBatchNo(batchNo);
invoiceVo.setLicenseNo(getLicenseNo(req.getBaseUserId()));
HashMap<String, String> channelMap = getChannelMap();
invoiceService.saveSubmitInvoice(req, channelMap, invoiceVo);
FixedThreadPoolUtil.INSTANCE.execute(() -> {
log.info("提现开票异步任务--开始");
List<WithdrawInvoice> withdrawInvoiceList = invoiceService.getWithdrawInvoiceList(batchNo);
if (CollectionUtils.isEmpty(withdrawInvoiceList)) {
return;
}
invoiceService.handleSubmitInvoice(withdrawInvoiceList);
withdrawInvoiceList.stream().forEach(withdrawInvoice -> {
InvoiceVo vo = makeupInvoiceVo(withdrawInvoice);
sendInvoiceEmail(vo, withdrawInvoice);
});
log.info("提现开票异步任务--结束");
});
} finally {
if (isAccess) {
redisTemplate.delete(invoiceKey);
}
}
}

锁失效原因

1. 删除锁之前发生异常

client1 获取到锁A,执行业务操作,这个时候服务发生异常,没有删除锁,导致别人无法操作。

方案: 设置过期时间

2. 过期时间到了,业务没执行完

client1 获取到锁A设置失效时间为十秒,执行业务操作花了20秒才处理完,但是锁已经不在了。

方案:可以把失效时间设置长点,但会影响性能

Redission架构

使用Lua脚本对redis进行加锁操作,确保业务执行的原子性。

看门狗会每隔10s检查客户端是否还持有锁,如果还持有就会延迟key的生存时间。

参考:https://www.cnblogs.com/AnXinliang/p/10019389.html

https://baijiahao.baidu.com/s?id=1730716661153081344&wfr=spider&for=pc

最新文章

  1. 基于 REST 的 Web 服务:基础
  2. poj1679 次小生成树
  3. [转]Linux中find常见用法示例
  4. Android 下拉刷新控件Android-PullToRefresh
  5. yii基础知识-应用
  6. quartz配置时间
  7. Mybatis基础学习(一)&mdash;初识MyBatis
  8. 封装一个button上带图片的,图片在上,文字在下的按钮
  9. js函数声明的三种方式
  10. Django 部署到Nginx
  11. wukong.go
  12. Java基础--面向对象编程4(多态)
  13. bootstrap_开始
  14. nodejs的某些api~(四)udp&amp;dns
  15. Solution of wireless link &quot;PCI unknown&quot; on Centos 7.1
  16. Codeforces 251C Number Transformation
  17. MyEclipse启动Tomcat缓慢的原因及解决办法
  18. 神奇的Flex 布局
  19. keepalived使用nc命令检测udp端口
  20. 【实战】Apache Shiro 1.2.4 RCE

热门文章

  1. SVN服务器的安装与使用
  2. 在 WXML 中使用 JS 代码
  3. .NET周报 【2月第4期 2023-02-25】
  4. PostgreSQL大表count方法总结及优化探讨
  5. PostgreSQL 谁堵塞了谁(锁等待检测)- pg_blocking_pids
  6. 跟女朋友介绍十个常用的 Python 内置函数,她夸了我一整天
  7. Django中多数据库的配置,实现分库分表,主从复制,读写分离
  8. 2、flex最后不对齐问题
  9. JDK的版本有多少种,Java开发者应该选择哪一种?
  10. 前端回血day24 flex子项伤的CSS属性