首页 > 其他分享 >幂等性解决方案

幂等性解决方案

时间:2024-09-18 12:23:02浏览次数:12  
标签:10 20231023 解决方案 id version ORD order

幂等性设计方案通常在分布式系统中,常见的幂等性设计方案如下:


1、唯一性约束

利用数据库的唯一性约束,如唯一索引或主键,来避免插入重复数据。


mysql> INSERT INTO `mydb`.`orders` (`order_id`, `user_id`, `product_id`, `quantity`, `order_status`, `create_time`, `pay_time`, `version`) VALUES ('ORD-20231023-0001', 'USR-A123456', 'PRD-X123', 2, 0, '2023-10-23 10:15:30', NULL, 1);

ERROR 1062 (23000): Duplicate entry 'ORD-20231023-0001' for key 'orders.PRIMARY'

注意:业务上要求生成全局唯一的主键。且不是自增策略,否则在分库分表的场景下,不同的表之间主键互不关联。


2. 乐观锁

 通过记录数据的版本号或时间戳,仅当数据未被其他事务修改时,才允许更新操作执行。每次更新数据时,版本号都会递增。


UPDATE orders

SET

 quantity = 1,

 order_status = 1,

 pay_time = '2024-04-30 10:20:00',

 version = version + 1

WHERE

 order_id = 'ORD-20231023-0001' AND

 version = 1;

效果演示:




如果 Session-01 已经提交了事务,Session-02 的更新操作将不会影响任何行,因为 version 已经从 1 增加到了 2。


3. 悲观锁

 使用悲观锁,事务在读取数据时会锁定相应的数据行,直到事务结束(提交或回滚)。这可以防止其他事务在锁定期间修改这些数据,从而确保数据的一致性。


在执行读取操作时,使用 SELECT ... FOR UPDATE 语句来锁定相关记录。


-- 锁定记录

SELECT * FROM orders WHERE order_id = 'ORD-20231023-0001' FOR UPDATE;

-- 执行业务逻辑

UPDATE orders SET quantity = 1, order_status = 1, pay_time = '2023-10-23 10:20:00' WHERE order_id = 'ORD-20231025-0003';

效果演示:




 由此可见,悲观锁确保每个事务也能安全地执行,而不会导致数据不一致的问题。但是,悲观锁可能会因为锁定机制而导致 性能问题 ,尤其是在高并发的系统中,这可能会引起 锁争用和死锁 。


4. 分布式锁

在分布式系统中,使用分布式锁来保证同一时间只有一个实例处理特定消息或请求。




当前使用redis分布式锁案例实现,


public class MyService {

   private final RedisDistributedLock lock;

   public MyService(Jedis jedis, String lockKey, int lockTimeout) {

       this.lock = new RedisDistributedLock(jedis, lockKey, lockTimeout);

   }

   public void executeInLock() {

       if (lock.tryLock()) {

           try {

               // 执行业务逻辑

           } finally {

               lock.unlock();

           }

       } else {

           // 处理无法获取锁的情况,例如重试或记录日志

       }

   }

}


这里顺便提一句,建议采用Lua脚本实现删除锁的逻辑,保证原子性。


public void unlock() {

       // 释放锁,使用Lua脚本来确保原子性

       String unlockScript = "if redis.call('get', KEYS[1]) == ARGV[1] then " +

                             "return redis.call('del', KEYS[1]) " +

                             "else " +

                             "return 0 " +

                             "end";

       jedis.eval(unlockScript, 1, lockKey, "1");



标签:10,20231023,解决方案,id,version,ORD,order
From: https://blog.51cto.com/u_16274468/12044977

相关文章

  • 一款EF Core下高性能、轻量级针对分表分库读写分离的解决方案
    前言今天大姚给大家分享一款EFCore下高性能、轻量级针对分表分库读写分离的解决方案,开源(ApacheLicense)的EFCore拓展程序包:ShardingCore。ShardingCore项目介绍ShardingCore是一款开源、简单易用、高性能、普适性,针对EFCore生态下的分表分库的扩展解决方案,支持EFCore2+的所有版......
  • 用户离线消息的Redis和RabbitMQ解决方案
    一、Redis在Redis中实现用户离线期间的消息接收,可以通过组合使用Redis的发布/订阅(Pub/Sub)功能和List数据结构来实现。具体来说,当用户离线时,可以将发送给该用户的消息存储在List中,待用户上线后再从List中读取消息。下面是一个详细的实现方案:1.设计数据结构为了实现......
  • 削峰+限流:秒杀场景下的高并发写请求解决方案
    哈喽,大家好!我是小米,一个29岁、活泼积极、热衷分享技术的码农。今天和大家聊一聊应对高并发的写请求这个主题,尤其是在大促、秒杀这种场景下,系统该如何应对突如其来的流量洪峰!每逢秒杀,瞬间涌入的请求量可能直接把你的系统给“砸”了。要如何应对这类场景呢?别着急,今天我就给大家从四个......
  • Win7玩游戏Ctrl和空格不能一起按的解决方案
    前几天在Windows7上玩《Minecraft》的时候,发现Ctrl和空格不能一起按,就开始研究,找到一个解决方案。首先打开控制面板,点击更改键盘或其他输入法,就会进入文本服务与输入语言。点击更改键盘,进入高级键设置选项卡,点击下面的快捷键,再点击更改按键顺序。如图,随便把快捷键改成一个你......
  • 《欢迎来到帕拉迪泽》qt5cored.dll丢失错误:一站式解决方案分享
    在《欢迎来到帕拉迪泽》这款游戏中,出现“qt5cored.dll丢失”的问题,可能由以下几个原因造成:一、原因分析安装问题:在游戏安装过程中,qt5cored.dll文件可能因安装程序未能完整执行而未被正确安装到系统目录中。安装包可能已损坏或不完整,导致某些文件未能成功安装。文件被删......
  • 博客园评论区头像换页更新解决方案
    前言博客园博客正文的评论区的每一条评论其实都是带用户头像链接的,因此有些博客主题利用这个链接,对评论新增了头像显示功能。但是这部分功能只能在第一次加载页面时有效,一旦出现评论翻页、排序等操作,头像又没了。为了解决这个问题,对#blog-comments-placeholder这个元素进行改......
  • 加油站智能监控系统改造解决方案
    加油站智能监控系统改造解决方案针对加油区、卸油区工作人员睡岗、工作时间抽烟、打电话等违反规定行为、明火烟雾、扬尘等异常现象,加油站智能监控系统改造解决方案针对卸油区:灭火器材置放不合理,卸油时工作人员换岗,静电释放时长不够,开展智能分析识别。如系统发现上述七种异常行为......
  • hadoop中小文件问题的解决方案
    鱼弦:公众号:红尘灯塔,CSDN内容合伙人、CSDN新星导师、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)Hadoop小文件问题解决方案Hadoop小文件问题是指在Hadoop中存储大量小文件时,会降低Hadoop的性能和效率。这是......
  • Android HandlerThread Post后延迟7秒才执行的原因及解决方案|如何提高Android后台线程
    在Android开发中,HandlerThread是用于处理后台线程任务的常见工具。然而,有时我们会遇到这样的问题:当任务通过HandlerThread的post方法发送后,任务的执行时间会出现明显的延迟,比如7秒的延迟才执行任务。本文将深入分析这种问题的成因,探讨可能的影响因素,并提供多种优化方案,帮助开发者解......
  • 如何恢复对帝国CMS的访问,忘记账号密码的解决方案
    如果你忘记了帝国CMS的后台管理员账号和密码,可以通过以下步骤来恢复对系统的访问:方法1:通过数据库重置密码登录数据库:使用数据库管理工具(如phpMyAdmin)连接到你的数据库。登录数据库管理界面。找到用户表:通常表名为 phome_enewsuser(具体表名可能有所不同)。打开表......