当前位置: 首页 > news >正文

Java高并发控制之按业务对象加同步锁

一、需求

        最常见的一个场景,账户余额更新! 业务场景稍复杂点,一个客户有多个虚拟余额账户,产生交易时,需要同时更新客户的多个余额账户,现在需要为余额更新做并发控制。

二、解决方案

        1、依赖数据的乐观锁,内存中不做更新余额的判断,update语句中增加条件,扣减的金额必须小于当前余额,代码中以返回的更新行数判断是否扣减成功。

        2、由于一些原因,逼着这里采用的是代码中加锁来解决的,首先需要明确一个前提,如下代码中加同步锁的方案是针对单节点的服务,若是多节点,则无法控制并发了。

三、核心代码

锁的颗粒度:最暴力的同步锁就是整个方法加同步,这样是以牺牲接口性能为代价一刀切的做法,笔者这里实现的是按客户余额账号加锁,同一个账号(账号唯一)更新余额加锁控制即可,不同的账户可以同时更新余额,逻辑上并不冲突。

/*** 账户信息*/
@Slf4j
@Component
public class AccountDemo{// 同步锁容器,一定注意容器必须是线程安全的private final Map<String, Object> accountLocks = new ConcurrentHashMap<>();public int updateBalance( String accountNo, long amount) {if (StrUtil.isBlank(accountNo)) {throw new ServiceException(EnumErrorCode.EC_COMMON_REQ_PARAM_ERROR);}if (amount == 0) {log.warn("amount is zero.");return 1;}// 根据账户ID获取或创建锁对象Object lock = accountLocks.computeIfAbsent(accountNo, k -> new Object());synchronized (lock) {// 判断客户余额是否充足if (checkBalance(accountNo, amount)) {throw new ServiceException("余额不足!"); }// 更新余额代码实现int update = updateBalance(accountNo, amount);}return update;}}

注意:该方法或方法上游加事务控制要特别小心,笔者在外层增加了事务控制,就导致了方法里面锁的执行顺序控制失效了!

http://www.lryc.cn/news/462175.html

相关文章:

  • Python魔法函数__iter__的用法
  • Redis-缓存一致性
  • SAP学习笔记 - 豆知识13 - Msg 番号 NR751 - Object RF_BELEG R100、番号範囲間隔 49 不存在 FBN1
  • 美摄科技云服务解决方案,方案成熟,接入简单
  • 【bug】paddleocr draw_ocr_box_txt ValueError: incorrect coordinate type
  • python的多线程和多进程
  • 基于SpringBoot+Vue+uniapp的时间管理小程序的详细设计和实现(源码+lw+部署文档+讲解等)
  • HMAC-MD5参数签名算法
  • 【word】文章里的表格边框是双杠
  • 我常用的两个单例模式写法 (继承Mono和不继承Mono的)
  • Android 自定义Toast显示View
  • SCRM呼叫中心高保真Axure原型 源文件分享
  • Ubuntu(Linux)tcpdump使用方法详解
  • Centos安装Nginx 非Docker
  • 免费版的音频剪辑软件:这四款有没有你的菜?
  • Facebook的隐私之战:数据保护的挑战与未来
  • 自定义注解和组件扫描在Spring Boot中动态注册Bean(二)
  • 常见网络协议的介绍、使用场景及 Java 代码样例
  • 音视频好文总结
  • 云服务器磁盘满了,清理docker无用缓存、容器等清理
  • Flutter flutter_native_splash 使用指南
  • 谷歌审核放宽,恶意软件不再封号?是反垄断案影响还是开发者们的错觉
  • C++实现一个线程池
  • 为什么inet_ntoa会返回错误的IP地址?
  • 编码风格之(8)C++语言规范(Google风格)3.md
  • openrtp 音视频时间戳问题
  • 了解Android中为什么需要多线程?
  • Kaggle Python练习:使用外部库(Exercise: Working with External Libraries)
  • React 子组件调用父组件的方法,以及互相传递数据
  • 爬虫基础---python爬虫系列2