基于rabbitMQ解决分布式事务

分布式事务解决方案之RabbitMQ 分布式事务问题 以电商业务为例,订单服务对应的订单数据库,库存服务对应的库存数据库,多个数据源之间存在了分布式事务问题。如何保证在订单生成后,正确的扣除库存,或者在订单生成失败时,还原扣除的库存,这就是分布式事务将要解决的问题。 解决分布式事务前的业务逻辑: @Transaction(rollbackFor=Exception.class) publicvoidcreateOrder(OrderInfoorderInfo)throwsException{ //订单... 阅读详情

常见的分布式事务解决方案:
1、基于数据库XA/JTA协议的方式: 需要数据库厂商支持;java组件有atomikos等
2、异步校对数据的方式: 支付宝、微信支付主动查询支付状态、对账单的形式
3、基于可靠消息的MQ解决方案: 异步场景;通用性强;扩展性较高
4、TCC编程式解决方案: 严选、阿里自己封装的DTX

课外读物:

https://my.oschina.net/dyyweb/blog/1633373

错误场景:

错误示例

调用接口失败时,订单系统事务回滚,提示用户操作失败
误以为这样的接口调用写法,就不会有分布式事务问题
问题:
1、运单系统可能已经进行执行操作,接口发生了异常(超时),订单系统数据进行回滚,导致数据不一致
2、接口成功,订单系统事务提交失败,运单系统没有回滚,数据不一致

解决步骤

基本架构

总结

优点:
1、通用性强
2、拓展性强
3、方案成熟
缺点:
1、基于消息中间件,只适用于异步场景(任务必须成功: 如,付了钱,必须有订单,有运单人)
2、消息处理会有延迟,需要业务上能容忍
尽量避免分布式事务
尽量将非核心事务做成异步(如扣钱,转账等还是同步)

spring事物和rabbitMQ的例子 spring的2个数据源的配置,并且每个数据源都配置了事物管理。还有rabbitMQ的发送端代码。本人项目亲自用到的,可以运行。 立即下载

相关推荐

Learning RabbitMQ mobi

Learning RabbitMQ 英文mobi 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

MQ选手终极对决:比较几个主流MQ实现分布式事务的方案

RabbitMQ 实现分布式事务的核心思想是将事务操作拆分为消息发送和确认两个阶段,通过确认消息的方式来实现事务的提交或回滚,从而确保分布式系统的数据一致性。在分布式事务的实现中,ACK消息和半消息是两种实现分布式事务的两种不同机制,它们的共同点是都使用了两阶段提交的机制,但是它们的实现细节和适用场景有所不同。使用 ACK 消息实现分布式事务时,需要将发送消息的操作包含在本地事务中,并在本地事务提交后发送 ACK 消息来确认消息的发送。通过以上步骤,RocketMQ 实现了分布式事务的核心思想。

Hanko的专栏 2003

RabbitMQ 原版书

很好的原版书,非常详细的介绍RabbitMQ的各个方面

SpringBoot分布式任务调度,可支持rabbitmq与kafka两种消息中间件的可回滚微服务实现。

分布式任务调度管理 Distribution task center. 支持Rabbit与kafka两种消息队列,实现立即执行与根据CronExpress表达式的执行及更加复杂的复合执行策略。在任务执行过程中可完成回滚操作。

weixin_44214515的博客 2863

Springboot2.X基于可靠消息rabbitmq最终一致性分布式事务+分布式全局唯一ID生成器

1、代码未实现部分      a、积分、红包相关代码未实现,按照下单逻辑操作即可      b、quatz调度未实现,这个相当简单,可以通过dubbo等rpc方式、或者httpclient方式进行远程调度,相关代码:            https://download.youkuaiyun.com/download/qq_22049773/12540998      c、其他均已实现      d、分布式全局ID生成器,ID生成非绝对递增有序,是趋向有序,这一点如果能接受,可以直接copy使用 2、事务回滚机制说明        a、每个消费端的事务处理都由本地事务负责        b、基于下单队列消费端临时表,查询红包、积分两个队列消费端的临时表中该订单的处理的状态,如果全部为消费成功,则更新业务订单表中的订单状态由  下单中  --》 待付款并删除所有临时表数据,如果非全部消费成功,则将定性为异常单并写入补单队列,并删除所有临时表数据。该逻辑有定时调度完成。

基于RabbitMQ消息队列的分布式事务解决方案

介绍Rabbitmg用于解决分布式事务必须掌握的5个核心概念一款分布式消息中间件,基于erlang语言开发,具备语言级别的高并发处理能力。和Spring框架是同一家公司。支持持久化、高可用1.Queue:真正存储数据的地方2.Exchange:接收请求,转存数据3.Bind:收到请求后存储到哪里4.消息生产者:发送数据的应用5.消息消费者:取出数据处理的应用分布式事务是一个业务问题,不能脱离具体的场景。●基于数据库XA/JTA协议的方式需要数据库厂商支持;JAVA组件有atomikos等●异步校对数据的方式支付宝、微信支付主动查询支付状态、对账单的形式;●基于可靠消息(MQ)的解决方案异步场景

分布式事务

本地消息表的最终一致方案采用BASE原理,保证事务最终一致。在一致性方面,允许一段时间内的不一致,但最终会一致。本地消息表实现分布式事务应该是网站前台使用最多的,其核心思想是将分布式事务拆分成本地事务进行处理,这种思路是来源于ebay。使用本地消息表,消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败,会进行重试发送。消息消费方,需要处理这个消息,并完成自己的业务逻辑。

m0_67463445的博客 2098

Docker深度详解:从原理到实践的全方位指南

本文深入解析了Docker容器化技术的核心原理与实战应用。主要内容包括:1) Docker核心架构与优势,对比容器与虚拟机的关键差异;2) 企业级部署方案,涵盖离线安装与多镜像源配置;3) 高级镜像构建技术,如参数化构建、缓存优化及安全扫描;4) 容器生命周期管理,包括健康检查、资源限制及数据持久化方案。文章提供了丰富的代码示例和生产级配置建议,如使用Trivy进行安全扫描、精确控制容器资源等技术细节,帮助开发者全面掌握现代容器化技术。

weixin_42593797的博客 1280

基于RabbitMQ解决分布式事务

1、可查询操作:服务操作具有全局唯一的标识,操作唯一的确定的时间。 2、幂等操作:重复调用多次产生的业务结果与调用一次产生的结果相同。一是通过业务操作实现幂等性,二是系统缓存所有请求与处理的结果,最后是检测到重复请求之后,自动返回之前的处理结果。 3、TCC操作:Try阶段,尝试执行业务,完成所有业务的检查,实现一致性;预留必须的业务资源,实现准隔离性。Confirm阶段:真正的去执行业务,不做任何检查,仅适用Try阶段预留的业务资源,Confirm操作还要满足幂等性。Cancel阶段:取消执行业务,释放T

Tiger_Paul的博客 2687

DIY必备:如何用N-MOS管搭建低成本DC有刷电机驱动电路(附原理图+避坑指南)

本文详细介绍了如何使用N-MOS管搭建低成本、高可靠性的DC有刷电机驱动电路。针对DIY爱好者,从核心原理、电路设计、元件选型到焊接调试,提供了完整的实战指南,并重点解析了续流二极管选型、栅极驱动设计等关键避坑要点,帮助读者成功驱动电机并确保电路稳定运行。

delta的博客 774

浅谈迪杰斯特拉(Dijkstra)算法和A*算法原理及实现

迪杰斯特拉(Dijkstra)算法和A*算法的原理及实现。

Guo_Zhanyu 9597

如何用 RabbitMQ 解决分布式事务?

要说哪种分布式事务处理方案效率高,必然绕不开消息中间件!基于消息中间件的两阶段提交方案,通常用在高并发场景下。这种方式通过牺牲数据的强一致性换取性能的大幅提升,不过实现这种方式的成本和复杂度是比较高的,使用时还要看实际业务情况。...

Java5658的博客 1601

海波龙(Oracle Hyperion)单点登陆问题记录

Oracle海波龙套件已经多年未更新,按Oracle官方文档实施单点登陆启用之后,SmartView工具通过专用链接方式无法登陆系统。 在抓包逆向分析之后 定位到HspSmartViewServlet类在执行以下代码时获得的ssotoken无效导致,在某大厂工作的时候曾通过在filter中截获请求的方式植入Attribute,保留账号密码并在单点程序中处理实现登陆。 但在完美世界的环境中...

cainiaoEzu的专栏 1970

rabbitmq-04 rabbitmq解决分布式事务

1.RabbitMQ消息重试机制 消费者在消费消息的时候,如果消费者业务逻辑出现程序异常,这时候应该如何处理? 答案:使用消息重试机制。(springboot默认有消息重试机制) 1.1 如何合适选择重试机制 消费者获取到消息后,调用第三方接口,但接口暂时无法访问,是否需要重试? (需要重试机制) 消费者获取到消息后,抛出数据转换异常,是否需要重试?(不需要重试机制)需要发布进行解决。 ...

沐宇熙IT成长之路 1万+

【OpenBMC 系列】4.启动流程 使用qume模拟ast2600-evb

1.安装openbmc适配的qume 2.启动bmc 3.使用bmc web

AiFool的博客 4458

微信聊天记录丢失原因与恢复方案详解

SQLite数据库作为移动应用常见的本地存储方案,其加密机制和存储结构直接影响数据安全性。以微信为例,聊天记录存储在EnMicroMsg.db等SQLite文件中,采用AES加密保护。当手机清理工具误删这些文件时,会导致特定时间段记录丢失。理解数据恢复原理需要掌握文件系统删除机制和闪存特性,其中关键点包括TRIM指令的影响和数据块覆盖风险。通过专业工具如DiskDigger或iMyFone D-Back,配合ADB调试和SQLite数据重组技术,可在黄金时间窗口内恢复记录。日常维护建议结合自动化备份方案和存

weixin_32612263的博客 386

RabbitMQ解决分布式事务

RabbitMQ解决分布式事务 案例: 经典案例,以目前流行点外卖的案例,用户下单后,调用订单服务,让后订单服务调用派单系统通知送外卖人员送单,这时候订单系统与派单系统采用MQ异步通讯。 RabbitMQ解决分布式事务原理: 采用最终一致性原理。 需要保证以下三要素1、确认生产者一定要将数据投递到MQ服务器中(采用MQ消息确认机制)2、MQ消费者消息能够正确消费消息,采用手动ACK模式,使用不...

art_code的博客 1565

SAP Joule 经过了超过 2.5 亿行 ABAP 代码的训练之后......

披露的统计数据,Joule 提供的这种全新系统交互方式,可将事务性任务执行速度提高 90%,访问 SAP Help Portal 内容的速度提高 95%。在 ABAP 应用开发领域,SAP 官网数据显示,Joule 经过超过 2.5 亿行 ABAP 代码的训练,有信心成为这一领域行业领先的代码助手。刚刚过去的 SAP 蓝宝石大会上,SAP 提到,从2023年第四季度以来,SAP 已经交付了 50 项基于人工智能的创新。让其生成 SAP 应用能够识别的结构化应用数据,业务用户全程无需离开 SAP 应用程序。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 792

rabbitmq mysql事务_RabbitMq解决分布式事务

1、分布式事务的常用解决方案(1)、基于数据库XA/JTA协议的方式;(需要数据库厂商的支持;java组件有atomikos等)(2)、异步校对数据的方式;(支付宝、微信支付主动查询支付转态、对账单的形式)(3)、基于可靠消息(MQ)的解决方案;(异步场景;通用性强;拓展性较高)(4)、TCC编程式解决方案。(严选、阿里、蚂蚁金服自己封装的DTX)2、使用rabbitmq解决分布式事务(1)、整体...

weixin_31693157的博客 531

论文阅读:NeurIPS 2024 JailbreakBench: An Open Robustness Benchmark for Jailbreaking Large Language Model

论文指出评估越狱攻击存在挑战,如缺乏评估标准、成本和成功率计算方法不一致、许多研究无法复现。为解决这些问题,作者提出了JailbreakBench,这是一个开源基准测试,包含以下组件:持续更新的越狱提示库(jailbreak artifacts)。包含100种行为的越狱数据集,符合OpenAI的使用政策。标准化的评估框架,包括威胁模型、系统提示、聊天模板和评分函数。跟踪各种LLMs攻击和防御性能的排行榜。

CSPhD-winston的博客 1431

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

SpringBoot整合消息中间件 RabbitMQ 第 10 篇 —— RabbitMQ 解决分布式事务(完结)

什么是分布式事务? 在微服务环境下,因为会根据不同的业务会拆分成不同的服务,比如会员服务、订单服务、商品服务等,每个服务都有自己独立的数据库,并且是独立运行,互不影响。在多数据源的情况下,两个服务相互通讯的时候,就会出现数据不一致的问题,从而出现分布式事务产生的原因。举例:某电商平台,用户先下单后,扣库存失败,那么将会导致超卖;如果下单不成功,扣库存成功,那么会导致少卖。 解决分布式事务基本思路 先了解一些概念:ACID原理、CAP、Base理论、柔性事务与刚性事务、理解最终一致性思想...

流放深圳 1304

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

基于RabbitMQ的分布式事务解决方案

一.分布式事物场景的一个错误示例 二.了解RabbitMQ 三.前言 - 分布式事物的几种解决方案 四.基于RabbitMQ的通用解决方案 整体设计思路 step1 - 可靠消息生产 - 记录消息发送 step2 - 可靠消息生产 - 修改消息发送状态 step3 - 可靠消息处理 - 正常处理 step4 - 可靠消息处理 - 消息重发 优缺点 ...

G0_hw 464

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

springboot分布式事务解决方案_基于RabbitMQ消息队列的分布式事务解决方案

1 极速了解MQ介绍Rabbitmg用于解决分布式事务必须掌握的5个核心概念一款分布式消息中间件,基于erlang语言开发, 具备语言级别的高并发处理能力。和Spring框架是同一家公司。 支持持久化、高可用核心5个概念:Queue: 真正存储数据的地方Exchange: 接收请求,转存数据Bind: 收到请求后存储到哪里消息生产者:发送数据的应用消息消费者: 取出数据处理的应用2、分布式事务问题...

weixin_39575648的博客 538

项目总结|我是如何用RabbitMQ解决分布式事务问题的

文章目录前言本地事务和分布式事务简单一说本地事务分布式事务项目解决方案RabbitMQ延时队列(实现定时任务)解决了最终一致性,怎么保证消息可靠呢?总结 前言 回顾之前做的b2c项目,在订单服务那块,涉及到分布式事务的问题,情景是这样的:提交订单的时候,需要创建一笔订单,并且还需要调用远程库存服务进行库存锁定,等到支付成功之后将这个锁定的库存减掉。这里就涉及到远程调用的时候就可能会出现两个事务状态不一致的情况 本地事务和分布式事务 简单一说 本地事务: 它是在一个服务内的事务 分布式事务: 在微服务下,

MarkusZhang的博客 3253
上一篇: mysql删除重复数据,并保留一条
下一篇: 记一次线上dubbo线程池爆满的问题 jedis 2.9源码问题
Kindle_code
博客等级 码龄12年 21粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值