1.背景上一篇我们使用Seata集成SpringBoot,本文使用Seata集成SpringCloud。同时,在上一篇文章的基础上,这里简单实现一下。二、项目结构三、实现功能:完成用户的下单操作,下单分为调用账户服务扣款和调用订单服务创建订单。四、项目中使用的技术SpringCloud、eureka、openfeign、seata、nacos、druid、mybatis-plus五、集成步骤1、引入spring-cloud-starter-alibaba-seatajar包com。alibaba.cloudspring-cloud-starter-alibaba-seata2021.1seata-spring-boot-starterio.seataio.seataseata-spring-boot-starter复制代码1.4.2参考文档:https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html二、业务库涉及的操作1.业务库undo_log表需要存在CREATETABLEIFNOTEXISTS`undo_log`(`branch_id`BIGINTNOTNULLCOMMENT'branchtransactionid',`xid`VARCHAR(128)NOTNULLCOMMENT'全局事务id',`context`VARCHAR(128)NOTNULLCOMMENT'undo_log上下文,比如序列化',`rollback_info`LONGBLOBNOTNULLCOMMENT'回滚信息',`log_status`INT(11)NOTNULLCOMMENT'0:normalstatus,1:defensestatus',`log_created`DATETIME(6)NOTNULLCOMMENT'createdatetime',`log_modified`DATETIME(6)NOTNULLCOMMENT'modifydatetime',UNIQUEKEY`ux_undo_log`(`xid`,`branch_id`))ENGINE=InnoDBCOMMENT='AT事务模式撤销表';2.业务表的主键业务表必须包含单列主键。如果有多个列主键,目前只有mysql支持3个。页面中最好不要自动更新时间戳自动更新时间戳业务表,使用手动更新,更新数据,只更新用到的数据.例如:表中有10个字段,当前业务只需要更新3个字段。这时,我们可以更新3个字段,而不是10个字段。如果默认更新update_time字段,则使用手动更新。三、启用数据源代理1、自动配置数据源代理seata:enabled:true#是否自动启用数据源代理enable-auto-data-source-proxy:true#数据源代理模式,使用AT模式data-source-proxy-mode:AT2,手动配置AT模式数据源代理1、配置文件关闭自动数据源代理seata:#是否自动开启数据源代理enable-auto-data-source-proxy:false2、配置配置数据源并以AT方式返回数据源必须是DataSourceProxy@BeanpublicDataSourcedataSourceProxy(){//一个数据源XxxDataSourcexxxDataSource=newXxxDataSource();//设置数据源的各种配置属性xxxDataSource.setXXX("");//使用DataSourceProxy包装returnnewDataSourceProxy(xxxDataSource);}4.传递xid引入spring-cloud-starter-alibaba-seata后,很多都实现了xid的自动传递。同时,分布式事务结束后,需要清除xid的值。默认实现了feign、rest、web中xids的传递。5.事务分组对应seataserver6.注册中心和配置中心应用程序中seata的配置中心和注册中心需要和seataserver一致。7.在业务方法中添加@GlobalTransactional注解在需要启动分布式事务的方法中添加@GlobalTransactional注解来启动分布式事务。公共类BusinessServiceImpl实现BusinessService{privatefinalOrderServiceorderService;privatefinalAccountClientaccountClient;@Override//开启分布式事务@GlobalTransactional(rollbackFor=Exception.class)publicvoidcreateAccountOrder(IntegeraccountId,Longamount,booleanhasExption){.println("xid:"+RootContext.getXID());//1.远程借记账户余额remoteDebit(accountId,amount);//2.下订单orderService.createOrder(accountId,amount);if(hasException){thrownewRuntimeException("发生异常,分布式事物需要滚动");}}privatevoidremoteDebit(IntegeraccountId,Longamount){Stringresult=accountClient.debit(accountId,amount);log.info("远程库存扣减结果:[{}]",result);}}6.分布式事务异常演示,事务回滚7.完整代码https://gitee.com/huan1993/spring-cloud-parent/tree/master/seata/seata-springcloud-mybatis-plus8.参考文档1,新人文档2,Seata常见问题