分布式事务
分布式事务实现与原理分析
1 分布式事务的理论基础
1.1 本地事务(基础回顾)
事务是关系型数据库中,由以组SQL组成的一个执行单元,该单元要么整体成功,要么整体失败.。
事务的ACID四大特性:
原子性(Atomicity)
指事务包含的所有sql执行,要么整体成功,要么整体失败。强调不可分割
一致性(Consistency)
事务执行之前和事务执行之后,预期的结果是一致的。比如转账的例子:比如张三余额是2000元,李四账户是:3000元。强调前后结果
无论转账多少次,结论都是相同的。
持久性(Durability)
一旦事务被提交了,数据就会落地到磁盘中。即使系统故障数据也不会丢失。
**隔离性(Isolation) **
是指多个并发,相互独立,相互隔离,互不影响。
mysql的隔离级别:
-
读未提交
-
读已提交
-
可重复读 (默认)
-
串行化
如果事务不进行隔离,会出现如下问题:
1:脏读,是指一个事务处理的过程中读取了另一个未提交(回滚)的事务的数据。
2:不可重复度:指多次查询却返回了不同的数据值,这是由于查询间隔的原因,被另一个事务修改并提交了。
3:幻读:指当A事务在读取某个范围内的记录时, B事务又在改范围内插入了新记录。当A事务再次读取该范围内的记录时,就产生了:幻读
幻读和不可重复读的区别:
- 相同点:幻读和不可重复读都是读到了另一个事务已经提交的数据,脏读是读取未提交的数据。
- 不同点:不可重复读读到都是同一个数据值(同一条记录数据),幻读是:是针对一批整体数据的数据(数据的总数或一张表)。
1.2 分布式事务
目标
掌握和了解本地事务和分布式事务的区别。
分析
1.2.1 本地事务
本地事务是关系型数据库中,由一组SQL组成的一个执行单元,该单元要么整体成功,要么整体失败。它的缺点就是:仅支持单库事务,并不支持跨库事务。
1.2.2 分布式事务
分布式事务是指:一个业务需要同时操作多个数据库的情况下,而且保持ACID的特性(数据的一致性),一般应用于微服务的多服务处理。
1.2.3 分布式事务场景
最早的分布式事务应用架构很简单,不涉及服务间的访问调用,仅仅是服务内操作涉及到对多个数据库资源的访问。
当一个服务操作访问不同的数据库资源,又希望对它们的访问具有事务特性时,就需要采用分布式事务来协调所有的事务参与者。
对于上面介绍的分布式事务应用架构,尽管一个服务操作会访问多个数据库资源,但是毕竟整个事务还是控制在单一服务的内部。如果一个服务操作需要调用另外一个服务,这时的事务就需要跨越多个服务了。在这种情况下,起始于某个服务的事务在调用另外一个服务的时候,需要以某种机制流转到另外一个服务,从而使被调用的服务访问的资源也自动加入到该事务当中来。下图反映了这样一个跨越多个服务的分布式事务:
如果将上面这两种场景(一个服务可以调用多个数据库资源,也可以调用其他服务)结合在一起,对此进行延伸,整个分布式事务的参与者将会组成如下图所示的树形拓扑结构。在一个跨服务的分布式事务中,事务的发起者和提交均系同一个,它可以是整个调用的客户端,也可以是客户端最先调用的那个服务。
较之基于单一数据库资源访问的本地事务,分布式事务的应用架构更为复杂。在不同的分布式应用架构下,实现一个分布式事务要考虑的问题并不完全一样,比如对多资源的协调、事务的跨服务传播等,实现机制也是复杂多变。
1.3 CAP定理
目标
掌握和了解什么是CAP定理
埃里克·布鲁尔(Eric Brewer)在《CAP 理论十二年回顾:“规则”变了》一文中详细地阐述了理解和应用 CAP 的一些细节点,可能是由于作者写作风格的原因,对于一些非常关键的细节点一句话就带过了,这里我特别提炼出来重点阐述。
C 一致性
A 可用性
P 分区容错性
分析
一句话概括CAP:在分布式系统中,即使网络故障,服务出现瘫痪,整个系统的数据保持一致性。
场景分析
美团下单到派单,并且扣除优惠券100元
张三在美团上点了外卖,然后下订单,然后在通知外卖小哥接单。思考三个问题:
1:如何体现C数据的 一致性
整个分布式系统中,一致性体现这笔订单,必须通知外卖小哥送单。必须扣除100元的优惠券。
2:如果体现A 可用性
在整个分布式系统中,可用性体现在张三下订单的时候,如果订单服务或卡券服务瘫痪了,这时候不能影响张三下单。(一般采用集群部署即可)
3:如何体现P分区容错性
整个分布式系统中,分区容错主要体现中张三下单的时候,突然订单服务和卡券服务之间的网络突然断开了,但是不能影响张三下订单。
项目A --> 项目B 卡卷
在分布式系统中,出现网络故障出现P,服务瘫痪A,整个系统的数据仍然保持一致性C。满足三者这种方案是做不到的。
相对可以是实现方案:业界的做法是:三选二。
当前服务之间出现网络故障的情况下:
1:如何保证订单服务和卡券服务高可用
2:下一笔订单同时扣除100元优惠券如何实现:
分布式系统解决方案:AP
1:CAP的(AP):牺牲一致性,保证高可用,(保证订单服务可以正常访问,保证卡券服务可以正常访问,是牺牲了数据的一致性),张三下单成功,但是不扣除100元优惠券。在这种情况下:张三下订单成功后再去查看100元,居然还存在。
如何解决呢?一般做法是:当网络恢复正常的情况下,订单服务重试请求卡券服务,再扣除100元优惠券。使用消息队列来做。
2:CAP的(CP):牺牲可用性,保证数据一致性,即未了保证数据的强一致性,当张三来下单的时候,提示:系统维护中
等服务间的网络恢复正常后,张三再来下单。
3:CAP的(CA):可以实现码?当然是不可以的,因为网络故障是一定会存在的,因为我们没办法去控制网络。你没办法去控制网络。也就是P必须要容忍。
思考:
不要P分区容错性,即不允许网络出现故障,这是不可能实现的。所以在分布式系统中,是不存在CA的,即使单体系统也做不到CA,因为单体系统也会出现单一故障问题。你可能说我可以用集群,但是一旦做了集群就由网络问题。
1.4 Base定理
BASE 是指基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency),核心思想是即使无法做到强一致性(CAP 的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性。
基本可用(Basically Available)
分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
这里的关键词是“部分”和“核心”,具体选择哪些作为可以损失的业务,哪些是必须保证的业务,是一项有挑战的工作。例如,对于一个用户管理系统来说,“登录”是核心功能,而“注册”可以算作非核心功能。因为未注册的用户本来就还没有使用系统的业务,注册不了最多就是流失一部分用户,而且这部分用户数量较少。如果用户已经注册但无法登录,那就意味用户无法使用系统。例如,充了钱的游戏不能玩了、云存储不能用了……这些会对用户造成较大损失,而且登录用户数量远远大于新注册用户,影响范围更大。
软状态(Soft State)
允许系统存在中间状态,而该中间状态不会影响系统整体可用性。这里的中间状态就是 CAP 理论中的数据不一致。
最终一致性(Eventual Consistency)
系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。
这里的关键词是“一定时间” 和 “最终”,“一定时间”和数据的特性是强关联的,不同的数据能够容忍的不一致时间是不同的。举一个微博系统的例子,用户账号数据较好能在 1 分钟内就达到一致状态。因为用户在 A 节点注册或者登录后,1 分钟内不太可能立刻切换到另外一个节点,但 10 分钟后可能就重新登录到另外一个节点了,而用户发布的微博,可以容忍 30 分钟内达到一致状态。因为对于用户来说,看不到某个明星发布的微博,用户是无感知的,会认为明星没有发布微博。“最终”的含义就是不管多长时间,最终还是要达到一致性的状态。
BASE 理论本质上是对 CAP 的延伸和补充,更具体地说,是对 CAP 中 AP 方案的一个补充。前面在剖析 CAP 理论时,提到了其实和 BASE 相关的两点:其实base理论就是告诉我们:虽然在分布式开发中,存在网络问题,我们虽然达不到一致性,但是可以通过一些技术和手段或者认为干预让我们数据达到最终一致性。
CAP 理论是忽略延时的,而实际应用中延时是无法避免的。
2 分布式事务的解决方案
分布式事务实现方案从类型上去分,分为刚性事务 和 柔型事务。
刚性事务:通常无业务改造,在CAP定理中主要满足的是CP,也就是强一致性,原生支持回滚/隔离性,适合低并发,短事务。 (金融类、银行类)
柔性事务:有业务改造,在CAP定理中主要满足的是BASE定理,也就是说允许在一定时间内出现数据不一致的情况,但要通过通知或补偿机制实现最终的数据一致性,适合高并发,适合长事务。(互联网项目)
2.1 刚性事务解决方案(CP)
2.1.1 2PC(基于XA 协议)
概述
2PC全称Two-phaseCommit,中文名是二阶段提交,是XA规范的实现思路,XA规范是 X/Open DTP 定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。XA 接口函数由数据库厂商提供。
JDBC
XA接口 远程管理其它数据库的事务
XA协议一套接口 通过这套接口可以远程的控制 数据库事务的操作
X/Open DTP是X/Open 组织(即现在的 Open Group )1994定义的分布式事务处理模型。XA规模型包括应用程序( AP )、事务管理器( TM )、资源管理器( RM )、通信资源管理器( CRM )四部分。一般,常见的事务管理器( TM )是交易中间件,常见的资源管理器( RM )是数据库,常见的通信资源管理器( CRM )是消息中间件。
2PC 通常使用到XA中的三个角色TM、AP
AP:事务发起方,通常为微服务自身;定义事务边界(事务开始、结束),并访问事务边界内的资源
TM:事务协调方,事务操作总控;管理事务全局事务,分配事务唯一标识,监控事务的执行进度,负责事务的提交、回滚、失败恢复。
RM:本地事务资源,根据协调方命令进行操作;管理本地共享资源(既数据库)。
2PC 分成2个阶段:
- 第一阶段:请求阶段(commit-request phase,或称表决阶段,voting phase)
- 第二阶段:提交阶段(commit phase)。
演示
java中基于XA协议的二阶段简单Demo演示
pom依赖:
<dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.10</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version></dependency></dependencies>
事务的发起者AP:
public class AP {public Connection getRmZhiFuBaoConn(){try {Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/alipay_zhifubao?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false","root","root");return connection;}catch (Exception ex){ex.printStackTrace();}return null;}public Connection getRmYuEBaoConn(){try {Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/alipay_yuebao?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false","root","root");return connection;}catch (Exception ex){ex.printStackTrace();}return null;}
}
TM事务管理器:
/*** 事务协调器代码:* 控制多个数据源的 1阶段事务预提交* 全部提交成功后* 控制多个数据源的 2阶段commit提交* 如果中间出现任何问题* 出发多个数据源的 全部rollback操作*/
public class TM { // 事务public void execute(Connection zfbConn,Connection yebConn) throws SQLException {// 是否打印XA的事务日志boolean logXaConmands = true;// 获取RM1的接口实例XAConnection xaConnection = new MysqlXAConnection((ConnectionImpl)zfbConn,logXaConmands);XAResource rm1 = xaConnection.getXAResource();// 获取RM2的接口实例XAConnection xaConnection2 = new MysqlXAConnection((ConnectionImpl)yebConn,logXaConmands);XAResource rm2 = xaConnection2.getXAResource();// 生成一个全局事务IDbyte[] globalid = "global_id_123456".getBytes(); // 全局事务IDint formateId = 1;Xid xid1 =null;Xid xid2 =null;try {/************************第一阶段-********事务准备**************************/// TM 把rmi的事务分支ID,注册到全局ID进行注册byte[] bqual1 = "xa0001".getBytes();xid1 = new MysqlXid(globalid,bqual1,formateId);// 事务开启-rm1的本地事务rm1.start(xid1,XAResource.TMNOFLAGS);// 支付宝 扣款String sql = "update t_account set amount = amount - 100 where username = 'xiaoming'";// 执行sqlPreparedStatement preparedStatement = zfbConn.prepareStatement(sql);preparedStatement.execute();// 事务结束rm1rm1.end(xid1,XAResource.TMSUCCESS);// TM 把rm2的事务分支ID,注册到全局ID进行注册byte[] bqual2 = "xa0002".getBytes();xid2 = new MysqlXid(globalid,bqual2,formateId);// 事务开启-rm2的本地事务rm2.start(xid2,XAResource.TMNOFLAGS);// 模拟用户购买一个商品,扣除红包10元String sql2 = "update t_account set amount = amount + 100 where username = 'xiaoming'";// 执行sqlPreparedStatement preparedStatement2 = yebConn.prepareStatement(sql2);preparedStatement2.execute();// 事务结束rm2结束rm2.end(xid2,XAResource.TMSUCCESS);// 准备提交int prepare1 = rm1.prepare(xid1);int prepare2 = rm2.prepare(xid2);/************************第一阶段- end ****************************************//************************第二阶段-*******事务提交*******************************/if(prepare1 == XAResource.XA_OK && prepare2 == XAResource.XA_OK){boolean onePharse = false;rm1.commit(xid1,onePharse);//提交事务rm2.commit(xid2,onePharse);//提交事务}else{rm1.rollback(xid1);//提交事务rm2.rollback(xid2);//提交事务}}catch (Exception ex){try {if(rm1!=null && xid1!=null){rm1.rollback(xid1);//提交事务}if(rm2!=null && xid2!=null){rm2.rollback(xid2);//提交事务}}catch ( Exception e){e.printStackTrace();}// 事务回滚ex.printStackTrace();}}
}
测试类:
/*** 测试类: 创建 AP TM对象* 通过TM对象管理全局事务*/
public class XATests {AP ap = new AP();TM tm = new TM();@Testpublic void xatest() throws Exception{tm.execute(ap.getRmZhiFuBaoConn(),ap.getRmYuEBaoConn());}
}
小结
1) 性能问题:所有参与者在事务提交阶段处于同步阻塞状态,占用系统资源,容易导致性能瓶颈。
**2) 可靠性问题:**如果协调者存在单点故障问题,或出现故障,提供者将一直处于锁定状态。
**3) 数据一致性问题:**在阶段 2 中,如果出现协调者和参与者都挂了的情况,有可能导致数据不一致。
**优点:**尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。
**缺点:**实现复杂,牺牲了可用性,对性能影响较大,不适合高并发高性能场景。
2.1.2 3PC(了解)
2PC是CP的刚性事务,追求数据强一致性。但是通过我们上面分析可以得知TM脑裂可能造成数据不一致和事务状态不确定问题。无法达到CP的完美状态。因此业界就出现了3PC,用来处理TM脑裂引起的数据不一致和事务状态不确定问题。
1)3PC确保任何分支下的数据一致性
2)3PC确保任何分支最多3次握手得到最终结果(超时机制)
3)RM超时后的事务状态必须从TM获取。2PC只有TM的超时机制,3PC新增了参与者(RM)的超时机制,一方面辅助解决了2PC的事务/事务问题,还能降低一定的同步阻塞问题。因为TM、RM双向超时机制,所以维基百科对3PC定义为“非阻塞”协议。
2.1.3 二阶段优化版(Seata AT模式)
概述
是seata框架中提供的一种模式,Atomic Transaction是基于两阶段提交协议的演变:
- 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
- 二阶段:
- 提交异步化,非常快速地完成。
- 回滚通过一阶段的回滚日志进行反向补偿。
详情参考: http://seata.io/zh-cn/docs/overview/what-is-seata.html
分布式事务是个复杂的问题,目前还没有任何一种解决方案可以非常完美地适应所有应用场景。
如果把分布式事务方案按 一致性、性能 和 易用性 这 3 个维度来考量:AT 模式,实际上是在业务需求允许的前提下,找到一个比较好的平衡点。编程模型不做改变的前提下,达到确定的一致性,而且保证了性能和系统可用性。
基于 Seata 的 AT 模式构建企业业务的分布式事务解决方案,可以带来以下 3 个方面的 核心价值:
- 低成本: 编程模型 不变,轻依赖 不需要为分布式事务场景做特定设计,业务像搭积木一样自然地构建成长。
- 高性能:协议不阻塞;资源释放快,保证业务的吞吐。
- 高可用:极端的异常情况下,可以暂时跳过异常事务,保证整个业务系统的高可用。
演示:
基于Seata框架实现,在事务发起方的方法上加GlobalTransactional注解即可
@GlobalTransactional
@Transactional
@Override
public int payToYuebao(String username, BigDecimal amount) {int i = accountMapper.minusAmount(username, amount);log.info("用户 : {} , 支付宝减钱: {} 操作成功" ,username,amount);yuebaoAddAmount(username,amount);// 制造异常 余额宝操作无法回滚// System.out.println(1/0);return i;
}
小结:
优点:
-
和基于XA的二阶段相比,性能高
-
和其它柔性事务相比,一致性强
-
业务代码侵入低,基于seata实现简单高效,且高可用
缺点:
- 基于ACID的关系型数据库
可以使用JDBC的java应用
2.2 柔性事务解决方案(BASE)
2.2.2 TCC (补偿型)
概述
TCC 是一种补偿型事务,该模型要求应用的每个服务提供 try、confirm、cancel 三个接口,它的核心思想是通过对资源的预留(提供中间态,如账户状态、冻结金额等),尽早释放对资源的加锁,如果事务可以提交,则完成对预留资源的确认,如果事务要回滚,则释放预留的资源。
- Try:尝试执行业务,完成所有业务检查(一致性),预留必要的业务资源(准隔离性)。
支付宝-钱 余额宝+钱
try: 预减钱 冻结: 100 try: 预加钱: 100
- Confirm:确认执行业务,不再做业务检查。只使用Try阶段预留的业务资源,Confirm操作满足幂等性。
Confirm: 确认执行业务: 冻结: 0 预加钱: 100 --> 主账户
- Cancel:取消执行业务释放Try阶段预留业务资源。
Cancel: 冻结: 100 ->加回支付宝账户 预加钱: 0
如: 支付宝 转账 到 余额宝案例改造
演示:
基于Seata的TCC模式实现,全部代课参考资料中代码:
/**
* 支付宝端服务接口
*/
@LocalTCC
public interface AccountService {@TwoPhaseBusinessAction(name="zhifubao_add",commitMethod = "confirmMinusAmount",rollbackMethod = "cancelMinusAmount")boolean tryMinusAmount(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "username")String username, @BusinessActionContextParameter(paramName = "amount")BigDecimal amount);boolean confirmMinusAmount(BusinessActionContext actionContext);boolean cancelMinusAmount(BusinessActionContext actionContext);
}
/*** 余额宝中的服务接口*/
@LocalTCC
public interface AccountService {@TwoPhaseBusinessAction(name="yuebao_add",commitMethod = "confirmAddAmount",rollbackMethod = "cancelAddAmount")boolean tryAddAmount(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "username")String username, @BusinessActionContextParameter(paramName = "amount")BigDecimal amount);boolean confirmAddAmount(BusinessActionContext actionContext);boolean cancelAddAmount(BusinessActionContext actionContext);
}
发起事务方法需要 设置全局事务注解
将每个事务参与者的 try方法执行
后续由TCC框架处理 提交或回滚操作
/*** 这里创建全局事务,调用每个事务参与者的try方法* 如果有一个try失败,直接抛出异常 抛出异常后seata会执行 cancel方法* 如果全部try执行成功, seata会执行 commit方法* @param username* @param amount* @return*/@GlobalTransactional@Overridepublic String doTransactionCommit(String username, BigDecimal amount) {//第一个TCC 事务参与者boolean result = accountService.tryMinusAmount(null,username, amount);if (!result) {throw new RuntimeException("支付宝扣减金额 失败==> 触发回滚");}//第二个TCC 事务参与者result = yuebaoAddAmount(username, amount);if (!result) {throw new RuntimeException("余额宝增加金额 失败==> 触发回滚");}return RootContext.getXID();}
小结:
优点:性能提升:具体业务来实现控制资源锁的粒度变小,不会锁定整个资源。数据最终一致性:基于 Confirm 和 Cancel 的幂等性,保证事务最终完成确认或者取消,保证数据的一致性。可靠性:解决了 XA 协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动管理器也变成多点,引入集群。缺点:
TCC 的 Try、Confirm 和 Cancel 操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本。
2.2.3 Saga (补偿型 了解)
概述:
Saga模型是把一个分布式事务拆分为多个本地事务,每个本地事务都有相应的执行模块和补偿模块(对应TCC中的Confirm和Cancel),当Saga事务中任意一个本地事务出错时,可以通过调用相关的补偿方法恢复之前的事务,达到事务最终一致性。
在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
理论基础:Hector & Kenneth 发表论⽂ Sagas (1987)
适用场景:
- 业务流程长、业务流程多
- 参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口
小结:
优势:
一阶段提交本地事务,无锁,高性能
事件驱动架构,参与者可异步执行,高吞吐
补偿服务易于实现缺点:
不保证隔离性
2.2.4 基于MQ+本地事务表 (异步通知)
概述
其核心思想是将分布式事务拆分成本地事务进行处理。并通过在数据库新建事务消息表,来记录事务消息的发送情况,处理情况,如果出现发送失败等情况,轮询事务消息表的数据重发事务消息,在基于消息队列完成事务的最终一致性。
事务1 消息通知 事务2
演示
如: 支付宝 转账 到 余额宝案例改造
支付宝账户的核心方法
@Service
@Slf4j
public class AccountServiceImpl implements AccountService {@AutowiredAccountDao accountDao;@AutowiredMessageDao messageDao;@AutowiredTransactionTemplate transactionTemplate;@AutowiredRabbitmqSender rabbitmqSender;// 优化细节, 使用编程事务 控制方法内事务的粒度// 防止发消息的操作出错 造成整个回滚
// @Transactional@Overridepublic void payToYuebao(String username, Integer amount) {// 手动编程事务 保证 减钱 和 添加消息数据到本地消息表 在一个事务中Message sendMsg = transactionTemplate.execute((transactionStatus)->{Message message = null;String msgId = UUID.randomUUID().toString().replaceAll("-","");// 1. 支付宝减钱int i = accountDao.minusAmount(username, new BigDecimal(amount));log.info("用户 : {} , 余额宝加钱: {} 操作成功" ,username,amount);// 2. 本地消息表添加事务消息if(i>0){message = new Message();message.setMsgId(msgId);message.setMsgStatus(MessageState.NO_CONSUMED);message.setUsername(username);message.setAmount(amount);messageDao.addMessage(message);}return message;});// 发消息操作 不需要在事务中,出错后 会有重试机制 重新发送消息if(sendMsg!=null){// 3. 发送消息到MQrabbitmqSender.sendMessage(MessageState.PAY_EXCHANGE,"zhifubao.pay",sendMsg);}}/*** 消费服务的回调方法* 暂时只处理消费成功的情况* @param param*/@Transactional@Overridepublic void payToYuebaoCallback(String param) {JSONObject jsonObject = JSONObject.parseObject(param);String msgId = jsonObject.getString("msgId");Message message = new Message();message.setMsgStatus(MessageState.HAS_CONSUMED);message.setMsgId(msgId);messageDao.updateMessage(message);}
}
发送消息的核心方法
@Slf4j
@Component
public class RabbitmqSender implements RabbitTemplate.ConfirmCallback {private RabbitTemplate rabbitTemplate;public RabbitmqSender(RabbitTemplate rabbitTemplate) {// 设置确认回调rabbitTemplate.setConfirmCallback(this);// 设置未投放到指定队列回调
// rabbitTemplate.setReturnCallback(this);this.rabbitTemplate = rabbitTemplate;}/*** 封装发送消息的方法* @param exchange* @param routekey* @param message*/public void sendMessage(String exchange, String routekey, Message message){try {log.info("发送消息给余额宝");rabbitTemplate.convertAndSend(exchange,routekey, JSONObject.toJSONString(message));} catch (AmqpException e) {log.error("发送消息给余额宝失败 ==> {}",e.getMessage());}}/*** 确认回调的处理方法* @param correlationData* @param b* @param s*/@Overridepublic void confirm(CorrelationData correlationData, boolean b, String s) {if(b){log.info("发送消息给余额宝 成功");}else {log.error("发送消息给余额宝 失败 ==> {}",s);}}
}
定时任务
定时检查本地消息表中未被消费的消息,进行定时的重新投递
@Slf4j
@Component
public class ScheduledService {@AutowiredMessageDao messageDao;@AutowiredRabbitmqSender rabbitmqSender;@Scheduled(cron = "0/20 * * * * ?")public void retrySendMsg(){log.info("定时器触发 检测未被消费消息");List<Message> messages = messageDao.queryMessageByState(MessageState.NO_CONSUMED);log.info("定时器触发 检测未被消费消息数量==> {}",( messages==null? 0 : messages.size()));for (Message message : messages) {log.info("重发消息======>");rabbitmqSender.sendMessage(MessageState.PAY_EXCHANGE,"zhifubao.pay",message);}}
}
余额宝消费消息的核心方法
一定要考虑幂等性
处理成功后需要异步通知
@Slf4j
@Component
public class MessageListener {@AutowiredAccountService accountService;@AutowiredStringRedisTemplate redisTemplate; // 使用redis处理幂等性@AutowiredTransactionTemplate transactionTemplate; // 编程事务对象@AutowiredRabbitTemplate rabbitTemplate;@RabbitListener(queues = MessageState.PAY_YEB_QUEUE)public void applyPayMsg(String messageJson){log.info("接收到 转账消息请求 消息内容==> {}",messageJson);try {// 模拟消费处理时间Thread.sleep(30000);} catch (InterruptedException e) {e.printStackTrace();}// 1. 接收传递过来的消息后,需要考虑幂等性Message msgObj = JSONObject.parseObject(messageJson, Message.class);// 2. redis中查看消息是否已经处理过Object handle_pay_msg = redisTemplate.boundHashOps("handle_pay_msg").get(msgObj.getMsgId());if(handle_pay_msg!=null){// 重复性消息 不在处理log.error("重复的余额宝转账消息 已忽略 流水号: {}",msgObj.getMsgId());return;}boolean handleResult = transactionTemplate.execute((state)->{int i = accountService.addAmount(msgObj.getUsername(), new BigDecimal(msgObj.getAmount()));if(i>0){redisTemplate.boundHashOps("handle_pay_msg").put(msgObj.getMsgId(),JSONObject.toJSONString(msgObj));return true;}return false;});if(handleResult){// 处理结束 回发确认消息JSONObject ackMsg = new JSONObject();ackMsg.put("msgId",msgObj.getMsgId());ackMsg.put("ack",true);rabbitTemplate.convertAndSend(MessageState.PAY_EXCHANGE,"yuebao.callback",ackMsg.toJSONString());log.info("余额宝处理转账完毕 异步回复确认消息到 支付宝 流水ID ==> {}",msgObj.getMsgId());}}
}
小结
优点:效率高,从应用设计开发的角度实现了消息数据的可靠性,消息数据的可靠性不依赖于消息中间件,弱化了对 MQ 中间件特性的依赖。缺点:与具体的业务场景绑定,耦合性强,不可公用。消息数据与业务数据同库,占用业务系统资源。业务系统在使用关系型数据库的情况下,消息服务性能会受到关系型数据库并发性能的局限。
2.2.3 基于MQ自身事务消息(异步通知 了解)
概述
Rocket
基于MQ的事务消息方案主要依靠MQ的半消息机制来实现投递消息和参与者自身本地事务的一致性保障。半消息机制实现原理其实借鉴的2PC的思路,是二阶段提交的广义拓展,流程图如下:
小结
优点:
消息数据独立存储,降低业务系统与消息系统之间的耦合。
吞吐量优于本地消息表方案。缺点:
大部分MQ没这功能
一次消息发送需要两次网络请求(half消息 + commit/rollback)。
需要实现消息回查接口。
3 分布式事务话术小结
3.1 前面小结
从互联网的公司角度出发:业务规避 > 柔性事务 > 刚性事务
业务规避:
从设计的角度避免分布式问题
刚性事务:
XA-2PC: 效率低,强一致性AT: 业务侵入性低,必须在关系型数据库和java支持JDBC项目中可以使用seata提供实现
柔性事务:
Saga: 适合业务流程复杂的长事务,不保证隔离性适合大型互联网公司,且事务涉及的流程特别复杂seata提供实现Tcc: 但业务侵入性强,每个功能都要提供try,confirm,cancel对资源依赖低,主要通过代码来保证一致性 有效的隔离了资源seata提供实现MQ: 效率最高,但与其实现与业务场景绑定紧密RocketMQ支持分布式事务消息其他MQ需要配合本地消息表实现
3.2 Seata是什么
Seata (原名: Fescar , 后更名Seata )是阿里巴巴推出一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务,
服务。https://seata.io/zh-cn/
解决分布式事务问题,有两个设计初衷
对业务无侵入:即减少技术架构上的微服务化所带来的分布式事务问题对业务的侵入 高性能:减少分布式事务解决方案所带来的性能消耗
Seata目前有三种分布式事务实现方案:AT、TCC及SAGA 及正在开发的XA方案
相关面试题
什么是事务及事务的特性?
事务 指的是一系列的操作,要么全部成功,要么全部失败。
在数据库中,指的是一个操作由一些列SQL组成,这些SQL看成一个整体,要么全部成功,要么全部失败。数据库中的事务满足ACID的特性
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)
什么是分布式事务?
在分布式架构中,一个操作可能横跨多个微服务,多个数据库,传统的本地事务无法解决,需要使用分布式事务来解决。
什么是CAP定理?
在分布式系统中,
C: 指的是多个系统中数据的一致性。
A: 指的是服务的高可用
P: 指的是分区容错即使网络故障的时候能够做到分区容错,在服务出现瘫痪时也能保证对应服务的高可用,而且整个系统的数据保持一致性。想完全满足以上3点是不可能的,所以业界主要选择3保2 优先保证两点,但分区容错和网络有关无法避免,所以P必须要保证 常见的两种方案:
CP: 保证一致性,分区容错
AP:保证高可用,分区容错
什么是Base定理?
Base定理,对CAP的平衡落地理论。
强调的是: 保证基本可用(核心服务高可用)允许存在软状态(运行出现一段时间的数据不一致情况)最终一致性(最终能够达到数据的一致性)
zk和eureka的区别?(从CAP的角度分析)
zk: cp 强调一致性
eureka: ap 强调高可用
分布式事务的解决方案?
刚性事务解决方案 (CP)基于XA的二阶段提交三阶段提交
柔性事务解决方案 (Base)TCC (补偿型)SAGA (补偿型)MQ事务消息 (异步通知)MQ+本地消息表 (异步通知)
seata介绍
阿里推出的一款开源的、一站式的分布式事务解决方案。 提供了TCC、SAGA、AT等模式的解决方案,XA二阶段模式也即将推出,适合各类微服务场景。在2019年1月左右开始推出最初版本,目前已经更新到1.2.1版本,由阿里的团队积极维护,而且社区非常活跃,是目前非常火的分布式事务解决方案
我们项目中分布式事务是如何处理的?
可以说使用seata框架, 不过最好在0.9以上版本 2019.10.16日发布0.9版本MQ+本地消息表的方式在过去使用的最多,因为可靠消息队列的异步通信效率很高。
不过需要针对特定的场景要做对应的设计,当子事务比较多时,或者要考虑各种补偿方案时实现比较复杂。
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- 1.格式化输出
1.%s(可以接受任意类型)1.1:值按照位置%s一一对应case "my name is %s and my age is %s" % ("zcy", "18")print(case)1.2:以字典方式传值,打破位置限制key:valuecase "我的名字是 %(name)s 我的年龄是%(age)s" % {"…...
2024/4/16 22:51:39 - 遥感 大气校正 6S代码参数设置
1. 几何条件(Geometrical conditions) 代码含义换行进行几何描述 1 Meteosat卫星 月 日 世界标准时 列数 行数 (最大尺寸5000*2500) 2GOES east卫星 月 日 世界标准时 列数 行数 (最大尺寸17000*12000) 3GOES west卫星 月 日 世界标准时 列数 行数 (最大…...
2024/4/30 8:58:09 - C++ stack容器详解
C stack容器stack容器的基本概念stack的常用接口1.构造函数2.赋值操作3.数据存取4.大小操作测试:stack容器的基本概念 stack是一种先进先出的数据结构,被称为栈,它只有一端可以出入。 栈中进入数据称为——入栈(push) 栈中弹出数据称为——出…...
2024/4/22 1:15:09 - QListWidget 类似于组合按钮
之前记录过QPushButton添加图片文字,通过QButtonGroup实现多个按钮只有一个可以被同时选中,与之相比,QListWidget的使用更为简洁,例子如下: QListWidgetItem* lwItem2 new QListWidgetItem(ui->listWidget); lwIt…...
2024/5/1 16:35:09 - JS递归求和
求1到100的和 function add(num1,num2){var sum num1num2;if(num21>100){return sum;}else{return add(sum,num21)}} var sum add(1,2);...
2024/5/2 10:13:09 - 不宁腿综合征是个啥?夜里睡不安稳可能是它在搞怪
刘大爷近来碰上个烦心事,睡眠时总觉得两条腿特别不舒服,不是觉得痒就是觉得麻木、火烧火燎,有时还感觉像有小蚂蚁在腿上爬来爬去,搅得大爷坐卧不宁,觉也睡不好,感觉吃饭也没以前香甜。带着疑问,…...
2024/4/23 9:42:46 - Vue项目实现文件下载进度条
Vue项目实现文件下载进度条 需求场景 大文件下载,花费的时间比较长,没有任何提示,用户体验很差。 需要优化,提示文件在下载中,并且显示进度百分比。 实现步骤 1.下载文件的方法,需要拿到当前进度。 2.每一…...
2024/4/26 23:14:23 - 410. 分割数组的最大值
给定一个非负整数数组 nums 和一个整数 m ,你需要将这个数组分成 m 个非空的连续子数组。 设计一个算法使得这 m 个子数组各自和的最大值最小。 示例 1: 输入:nums [7,2,5,10,8], m 2 输出:18 解释: 一共有四种方…...
2024/4/28 19:16:24 - 用switch语句
/*将学生成绩按不同的分数段分为优,良,中,及格和不及格五个等级,从键盘上输入一个数0~100,输出相应的等级。要用swithc语句 */import java.util.Scanner; public class switchTest {public static void main(String[] …...
2024/4/26 12:15:35 - 杰理之LINEIN 的 ADC 后,播放久了有规律的 POPO 声【篇】
数据不同步,导致后面没隔 相同的 10 几秒就有丢包的哒一声的出来...
2024/4/21 21:38:58 - 杰理之获取设备(U 盘 /SD 卡)等的剩余容量接口不支持问题【篇】
使用 int fget_free_space(const char *path, u32 *space) extern 这个来用,直接传路径, space 返回大小...
2024/5/1 5:55:48 - 【预测模型】基于Elman神经网络预测电力负荷matlab代码
1 简介 为提高甘肃电网负荷预测精度,提出了一种基于神经网络的负荷预测方法.针对甘肃电力系统负荷数据的非线性和动态特性,在多层前向BP网络中引入特殊关联层,形成有"记忆"能力的Elman神经网络,从而可以映射系统的非线性和动态特性.在网络训练算法中,采用自适应学…...
2024/4/26 11:52:41 - 杰理之支持 exfat 文件系统的写补丁【篇】
主要表现为:在 exfat 文件系统下会出现录不了音 修复步骤: 1. 替换库文件 2...
2024/4/30 19:04:46 - 22 | 轻量级沟通:你总是在开会吗?
今天我们来探讨一个很多程序员日常工作中,经常碰到却会带来困扰的话题:开会。 头疼的开会 有一次,我听到两个程序员在聊天。一个资深程序员说:“还是晚上好,我可以一门心思写代码”,另一个年轻程序员不解地…...
2024/4/25 18:10:50 - Android IPC机制(四)用ContentProvider进行进程间通信
相关文章: Android IPC机制(一)开启多进程 Android IPC机制(二)用Messenger进行进程间通信 Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用前言ContentProvider为存储和获取数据提供统一的接口,它可以在不同的应用程序之间共享数据,本身就是适合进…...
2024/4/15 21:26:54 - Maven的安装配置和Idea使用
这里写目录标题注意Maven的安装需要Java的JDKMaven的下载配置Maven的环境变量设置settings.xml文件IDEA中的maven配置注意Maven的安装需要Java的JDK JDK的安装教程请参考: https://blog.csdn.net/hznb_369/article/details/120297168?utm_sourceapp&app_versi…...
2024/4/25 17:31:37 - ipfrag_low_thresh,ipfrag_high_thresh
没有正确重组的包都需要存在reassembly buffer里面,存的数据包数量超过reassembly buffer的上限后自然会被丢弃。 所以当使用 netstat -s 命令发现很多 reassembles failed ,则需要调整 reassembly buffer 的大小,该大小由下面两个系统参…...
2024/4/22 5:38:37 - 杰理之的动态切换 LINEIN AMUXN 通道的问题【篇】
记得#define TCFG_DEC_PCM_ENABLE ENABLE 的 PCM 解码要打开! //20210603 void APP_switch_linein_ch(int ch) { SFR(JL_ANA->DAA_CON2, 1, 1, 0);//LIN0L_EN SFR(JL_ANA->DAA_CON2, 5, 1, 0);//LIN1L_EN SFR(JL_ANA->DAA_CON2, 3, 1, 0);//LIN0R_EN SFR(J…...
2024/4/26 6:43:42 - pytorch-GPU版本训练LSTM模型,提示输入和hidden隐藏层不在一个设备上,一个GPU,而隐藏层在cpu
input and hidden tensors are not at the same device,found input tensor at cpu and parameter at cuda:0 这个问题解决方法还是比较简单的,只需要在模型中定义的hidden的函数上将hidden.to(device)即可,如果使用的BiLSTM会提示无法把元组进行to(dev…...
2024/4/27 22:52:41 - Spring的bean线程是否安全
Spring的作用域: 单例 多例 单例:意味内存中只有一个实例,如果你定义了一个成员变量此时线程来同时访问并还没保证成员变量的原子性操作,此时就会有线程安全问题 解决方案: 枷锁 ThreadLocal 多例:没有安全…...
2024/4/21 13:39:18
最新文章
- Java各种List实现类以及特点
目录 1. ArrayList 2. LinkedList 3. Vector 4. Stack 5. CopyOnWriteArrayList 1. ArrayList 特性: 基于动态数组实现。提供快速的随机访问能力。在列表末尾添加/删除元素非常快,但在列表中间插入/删除元素可能需要移动元素,较慢。每次自动增长时…...
2024/5/2 14:29:30 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - Go语言map、slice、channel底层实现(go面试)
slice 切片是一个引用类型,其底层实现是一个结构体,包含以下字段: ptr:一个指向底层数组的指针,指针指向数组的第一个元素。 len:切片当前包含的元素数量。 cap:切片的容量,即底层…...
2024/4/29 18:34:36 - GIS与数字孪生共舞,打造未来智慧场景
作为一名数字孪生资深用户,近日我深刻理解到GIS(地理信息系统)在构建数字孪生体中的关键作用。 数字孪生技术旨在构建现实世界的虚拟镜像,而GIS则是这一镜像中不可或缺的空间维度框架和导航灯塔。数字孪生的核心是通过数字化方式…...
2024/5/2 2:35:02 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/1 17:30:59 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/4/30 18:14:14 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/29 2:29:43 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/2 9:28:15 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/27 17:58:04 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/27 14:22:49 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/28 1:28:33 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/30 9:43:09 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/27 17:59:30 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/4/25 18:39:16 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/28 1:34:08 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/26 19:03:37 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/29 20:46:55 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/30 22:21:04 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/1 4:32:01 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/27 23:24:42 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/28 5:48:52 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/30 9:42:22 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/2 9:07:46 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/30 9:42:49 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57