Java分布式事务(七)
文章目录
- 🔥Seata提供XA模式实现分布式事务_业务说明
- 🔥Seata提供XA模式实现分布式事务_下载启动Seata服务
- 🔥Seata提供XA模式实现分布式事务_转账功能实现上
- 🔥Seata提供XA模式实现分布式事务_转账功能实现下
🔥Seata提供XA模式实现分布式事务_业务说明

业务说明
本实例通过Seata中间件实现分布式事务,模拟两个账户的转账交易
过程。两个账户在两个不同的银行(张三在bank1、李四在bank2),bank1和bank2是两个微服务。交易过程中,张三给李四转账制定金额。上述交易步骤,要么一起成功,要么一起失败,必须是一个整体性的事务。

工程环境
| 服务名称 | 服务版本 |
|---|---|
| 数据库 | MySQL-5.7.25 |
| JDK | 1.8 |
| 微服务框架 | Spring-boot-2.6.3、Spring-Cloud-2021.0.0、Spring-Cloud-Alibaba-2021.0.1.0 |
| Seata客户端(RM、TM) | Spring-cloud-alibaba-seata-2021.0.1.0 |
| Seata服务端(TC) | Seata-server-1.4.2 |
| 服务注册 | Nacos |
| Mybatis plus | 3.5.1 |
创建数据库
bank1库,包含张三账户
CREATE DATABASE /*!32312 IF NOT EXISTS*/bank1;
/*!40100 DEFAULT CHARACTER SET utf8 */;
USE bank1;
/*Table structure for table account_info */
DROP TABLE IF EXISTS account_info;
CREATE TABLE account_info (id bigint(20) NOT NULL AUTO_INCREMENT,
account_name varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '户主姓名',
account_no varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '银行卡号',
account_password varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '帐户密码',account_balance double DEFAULT NULL COMMENT '帐户余额',
PRIMARY KEY (id) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULTCHARSET=utf8 COLLATE=utf8_bin
ROW_FORMAT=DYNAMIC;
/*Data for the table `account_info` */
insert into
account_info(id,account_name,account_no ,account_password,account_balance) values
(2,'张三','1',NULL,1000);
bank2库,包含李四账户
CREATE DATABASE /*!32312 IF NOT EXISTS*/bank2
/*!40100 DEFAULT CHARACTER SET utf8 */;
USE bank2;
/*Table structure for table account_info */
DROP TABLE IF EXISTS account_info;
CREATE TABLE account_info (
id bigint(20) NOT NULL AUTO_INCREMENT,
account_name varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '户主姓名',
account_no varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '银行卡号',
account_password varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '帐户密码', account_balance double DEFAULT NULL COMMENT '帐户余额',
PRIMARY KEY (id) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT
CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC;
/*Data for the table `account_info` */
insert into account_info(id,account_name,account_no,account_password,account_balance) values(3,'李四','2',NULL,0);
🔥Seata提供XA模式实现分布式事务_下载启动Seata服务

下载seata服务器
下载地址:https://github.com/seata/seata/releases

解压并启动
tar -zxvf seata-server-1.4.2.tar.gz -C
/usr/local/
#后台运行
nohup sh seata-server.sh -p 9999 -h
192.168.66.100 -m file &> seata.log &
注意:
其中9999为服务端口号;file为启动模式,这里指seata服务将采用文件的方式存储信息。
测试
查看启动日志
cat seata.log

Seata提供XA模式实现分布式事务_搭建聚合父工程构建
创建工程distribute-transaction
tar -zxvf seata-server-1.4.2.tar.gz -C
/usr/local/
#后台运行
nohup sh seata-server.sh -p 9999 -h
192.168.66.100 -m file &> seata.log &
cat seata.log
71
字符编码
注解生效激活
72
Java编译版本选择
org.apache.maven.plugins
maven-compilerplugin
1.8
1.8
UTF-8
73
File Type过滤
pom配置版本
<spring-boot.version>2.6.3</springboot.version>
<spring.cloud.version>2021.0.1</spring.cloud.v
ersion>
<spring.cloud.alibaba.version>2021.0.1.0</spri
ng.cloud.alibaba.version>
<lombok.version>1.18.22</lombok.version>
74
75
org.springframework.boot
spring-bootstarter-parent
${spring-boot.version}
pom
import
org.springframework.cloud
spring-clouddependencies
${spring.cloud.version}
pom
import
com.alibaba.cloud
spring-cloudalibaba-dependencies
${spring.cloud.alibaba.version}
IDEA开启Dashboard
普通的Run面板
Run Dashboard面板
pom
import
org.projectlombok
lombok
${lombok.version}
76
修改配置文件
在.idea/workspace.xml 文件中找到
添加配置
Seata提供XA模式实现分布式事务_转账功能实现上
🔥Seata提供XA模式实现分布式事务_转账功能实现上
实现如下功能
⭐李四账户增加金额。
创建bank2

pom引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starterweb</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-bootstarter</artifactId><version>3.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connectorjava</artifactId><version>5.1.49</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starteralibaba-nacos-discovery</artifactId></dependency>
编写主启动类
//添加对mapper包扫描 Mybatis-plus
@MapperScan("com.it.mapper")
@SpringBootApplication
@Slf4j
//开启发现注册
@EnableDiscoveryClient
public class SeataBank2Main6002 {public static void main(String[] args) {SpringApplication.run(SeataBank1Main6002.class
,args);log.info("**************
SeataBank1Main6002 *************");}
}
编写YML配置文件
server:port: 6002
spring:application:name: seata-bank2
cloud:nacos:discovery:# Nacos server地址server-addr: 192.168.66.101:8848datasource:url: jdbc:mysql://localhost:3306/bank2?
useUnicode=true&characterEncoding=utf-
8&useSSL=false&serverTimezone=UTCusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driver
代码生成
引入Mybatis Plus代码生成依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plusgenerator</artifactId><version>3.5.2</version></dependency><!-- 模板引擎 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-enginecore</artifactId><version>2.0</version></dependency>
生成代码
package com.it.utils;
import
com.baomidou.mybatisplus.generator.FastAutoGenerator;
import
com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.Arrays;
import java.util.List;
public class CodeGenerator {public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql://192.168.66.100:3306/bank2", "root", "123456").globalConfig(builder -> {builder.author("it")
// 设置作者.commentDate("MM-dd") // 注释日期格式.outputDir(System.getProperty("user.dir")+
"/xa-seata/bank2"+ "/src/main/java/") // 指定输出目录.fileOverride(); // 覆盖文件})// 包配置.packageConfig(builder -> {
builder.parent("com.it") // 包名前缀.entity("entity")
//实体类包名.mapper("mapper")
//mapper接口包名.service("service"); //service包名}).strategyConfig(builder -> {// 设置需要生成的表名List<String> strings =
Arrays.asList("account_info");builder.addInclude(strings)
// 开始实体类配置
.entityBuilder()
// 开启lombok模型
.enableLombok()
//表名下划线转驼峰
.naming(NamingStrategy.underline_to_camel)
//列名下划线转驼峰
.columnNaming(NamingStrategy.underline_to_camel
);}).execute();}
}
编写转账接口
public interface IAccountInfoService {//李四增加金额void updateAccountBalance(String accountNo,Double amount);
}
编写转账接口实现类
@Service
@Slf4j
public class AccountInfoServiceImpl implements IAccountInfoService {@AutowiredAccountMapper accountMapper;@Overridepublic void updateAccountBalance(String
accountNo, Double amount) {// 1. 获取用户信息AccountInfo accountInfo =
accountMapper.selectById(accountNo);accountInfo.setAccountBalance(accountInfo.getAccountBalance() + amount);accountMapper.updateById(accountInfo);}
}
编写控制层
@RestController
@RequestMapping("/bank2")
public class Bank2Controller {@AutowiredIAccountInfoService accountInfoService;//接收张三的转账@GetMapping("/transfer")public String transfer(Double amount){//李四增加金额accountInfoService.updateAccountBalance("3",amount);return "bank2"+amount;}
}
🔥Seata提供XA模式实现分布式事务_转账功能实现下
实现如下功能
⭐张三账户减少金额
⭐远程调用bank2向李四转账。
pom引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-bootstarter</artifactId><version>3.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connectorjava</artifactId><version>5.1.49</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starteralibaba-nacos-discovery</artifactId></dependency><!-- openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starteropenfeign</artifactId></dependency><dependency>
<groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starterloadbalancer</artifactId></dependency>
编写主启动类
//添加对mapper包扫描 Mybatis-plus
@MapperScan("com.it.mapper")
//开启OpenFiegn
@EnableFeignClients
@SpringBootApplication
@Slf4j
//开启发现注册
@EnableDiscoveryClient
public class SeataBank1Main6001 {public static void main(String[] args) {SpringApplication.run(SeataBank1Main6001.class,args);log.info("**************
SeataBank1Main6001 *************");}
}
编写YML配置文件
server:port: 6001
spring:application:name: seata-bank1cloud:nacos:discovery:# Nacos server地址server-addr: 192.168.66.101:8848datasource:url: jdbc:mysql://localhost:3306/bank1?
useUnicode=true&characterEncoding=utf-
8&useSSL=true&serverTimezone=UTCusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driver
创建实体类
@AllArgsConstructor
@NoArgsConstructor
@Builder
@TableName("account_info")
@Data
public class AccountInfo {//id@TableIdprivate Long id;//户主姓名@TableField("account_name")private String accountName;//银行卡号@TableField("account_no")private String accountNo;//账户密码@TableField("account_password")private String accountPassword;//账户余额@TableField("account_balance")private Double accountBalance;
}
编写持久层
@Component
@Mapper
public interface AccountMapper extends
BaseMapper<AccountInfo> {
}
编写转账接口
public interface IAccountInfoService {//张三扣减金额public void updateAccountBalance(String
accountNo, Double amount);
}
编写远程调用接口
@Component
@FeignClient(value="seata-bank2")
public interface Bank2Client {//远程调用李四的微服务@GetMapping("/bank2/transfer")String transfer(@RequestParam("amount")
Double amount);
}
编写转账接口实现类
@Service
@Slf4j
public class AccountInfoServiceImpl implements IAccountInfoService {@AutowiredAccountMapper accountMapper;@AutowiredBank2Client bank2Client;@Overridepublic void updateAccountBalance(String
accountNo, Double amount) {// 1. 获取用户信息AccountInfo accountInfo =
accountMapper.selectById(2);// 2. 判断张三账户余额是否有钱if (accountInfo.getAccountBalance() >
amount){//扣减张三的金额accountInfo.setAccountBalance(accountInfo.getAccountBalance()-amount);int result =
accountMapper.updateById(accountInfo);if (result!=0){//调用李四微服务,转账bank2Client.transfer(amount);}}}
}
编写控制层
@RestController
public class Bank1Controller {@AutowiredIAccountInfoService IAccountInfoService;//张三转账@GetMapping("/transfer")public String transfer(Double amount){IAccountInfoService.updateAccountBalance("1",amount);return "bank1"+amount;}}
相关文章:
Java分布式事务(七)
文章目录🔥Seata提供XA模式实现分布式事务_业务说明🔥Seata提供XA模式实现分布式事务_下载启动Seata服务🔥Seata提供XA模式实现分布式事务_转账功能实现上🔥Seata提供XA模式实现分布式事务_转账功能实现下🔥Seata提供X…...
二十八、实战演练之定义用户类模型、迁移用户模型类
1. Django默认用户模型类 (1)Django认证系统中提供了用户模型类User保存用户的数据。 User对象是认证系统的核心。 (2)Django认证系统用户模型类位置 django.contrib.auth.models.User(3)父类AbstractUs…...
Java Virtual Machine的结构 3
1 Run-Time Data Areas 1.1 The pc Register 1.2 Java Virtual Machine Stacks 1.3 Heap 1.4 Method Area JVM方法区是在JVM所有线程中共享的内存区域,在编程语言中方法区是用于存储编译的代码、在操作系统进程中方法区是用于存储文本段,在JVM中方法…...
linux ubuntu22 安装neo4j
环境:neo4j 5 ubuntu22 openjdk-17 neo4j 5 对 jre 版本要求是 17 及以上,且最好是 openjdk,使用比较新的 ubuntu 系统安装比较好, centos7 因为没有维护,yum 找不到 openjdk-17了。 官方的 debian 系列安装教程&a…...
模型实战(7)之YOLOv8推理+训练自己的数据集详解
YOLOv8推理+训练自己的数据集详解 最近刚出的yolov8模型确实很赞啊,亲测同样的数据集用v5和v8两个模型训练+预测,结果显示v8在检测精度和准确度上明显强于v5。下边给出yolov8的效果对比图: 关于v8的结构原理在此不做赘述,随便搜一下到处都是。1.环境搭建 进入github进行git…...
火车进出栈问题 题解
来源 卡特兰数 个人评价(一句话描述对这个题的情感) …~%?..,# *☆&℃$︿★? 1 题面 一列火车n节车厢,依次编号为1,2,3,…,n。每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种。 输入…...
Unity学习日记12(导航走路相关、动作完成度返回参数)
目录 动作的曲线与函数 创建遮罩 导航走路 设置导航网格权重 动作的曲线与函数 执行动作,根据动作完成度返回参数。 函数,在代码内执行同名函数即可调用。在执行关键帧时调用。 创建遮罩 绿色为可效用位置 将其运用到Animator上的遮罩,可…...
基于bearpi的智能小车--Qt上位机设计
基于bearpi的智能小车--Qt上位机设计 前言一、界面原型1.主界面2.网络配置子窗口模块二、设计步骤1.界面原型设计2.控件添加信号槽3.源码解析3.1.网络链接核心代码3.2.网络设置子界面3.3.小车控制核心代码总结前言 最近入手了两块小熊派开发板,借智能小车案例,进行鸿蒙设备学…...
汇编语言与微机原理(1)基础知识
前言(1)本人使用的是王爽老师的汇编语言第四版和学校发的微机原理教材配合学习。(2)推荐视频教程通俗易懂的汇编语言(王爽老师的书);贺老师C站账号网址;(3)文…...
ASEMI代理瑞萨TW8825-LA1-CR汽车芯片
编辑-Z TW8825-LA1-CR在单个封装中集成了创建多用途车载LCD显示系统所需的许多功能。它集成了高质量的2D梳状NTSC/PAL/SECAM视频解码器、三重高速RGB ADC、高质量缩放器、多功能OSD和高性能MCU。TW8825-LA1-CR其图像视频处理能力包括任意缩放、全景缩放、图像镜像、图像调整和…...
什么是 .com 域名?含义和用途又是什么?
随着网络的发展,网络上出现了各种不同后缀的域名,这些域名的后缀各有不同的含义,也有不同的用途。今天,我们就一起来探讨一下 .com 后缀的域名知识。 .com 域名是一种最常见的顶级域名,它是由美国国家网络信息中心&…...
VueX快速入门(适合后端,无脑入门!!!)
文章目录前言State和Mutations基础简化gettersMutationsActions(异步)Module总结前言 作为一个没啥前端基础(就是那种跳过js直接学vue的那种。。。)的后端选手。按照自己的思路总结了一下对VueX的理解。大佬勿喷qAq。 首先我们需要…...
前列腺癌论文笔记
名词解释 MRF: 磁共振指纹打印技术( MR Fingerprinting)是近几年发展起来的最新磁共振技术,以一种全新的方法对数据进行采集、后处理和实现可视化。 MRF使用一种伪随机采集方法,取代了过去为获得个体感兴趣的参数特征而使用重复系列数据的采集方法&…...
Python+Yolov5道路障碍物识别
PythonYolov5道路障碍物识别如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助!前言这篇博客针对<<PythonYolov5道路障碍物识别>>编写代码,代码整洁,规则,易读。 学习与…...
全新升级,EasyV 3D高德地图组件全新上线
当我们打开任意一个可视化搭建工具或者搜索数据可视化等关键词,我们会发现「地图」是可视化领域中非常重要的一种形式,对于许多可视化应用场景都具有非常重要的意义,那对于EasyV,地图又意味着什么呢?EasyV作为数字孪生…...
从管理到变革,优秀管理者的进阶之路
作为一位管理者,了解自身需求、企业需求和用户需求是非常重要的。然而,仅仅满足这些需求是不够的。我们还需要进行系统化的思考,以了解我们可以为他人提供什么价值,以及在企业中扮演什么样的角色。只有清晰的自我定位,…...
安装Anaconda3
安装Anaconda3 下载安装文件 可以去官网下载 https://repo.anaconda.com/archive/根据自己的操作系统选择合适的Anaconda版本 我选择的是Anaconda3-2021.05-Linux-x86_64.sh的版本 方法一:可以下载到本地然后在上传到虚拟机 方法二:在终端输入以下…...
HTTPS,SSL(对称加密和非对称加密详解)
上一篇博客(HTTP详解_徐憨憨!的博客-CSDN博客)详细讲解了关于HTTP的知识,了解到HTTP协议下的数据传输是一种明文传输,既然是明文传输,可能导致在传输过程中出现一些被篡改的情况,此时就需要对所…...
【数据结构】还不懂算法复杂度?一文带你速解
前言:前面我们已经系统的学完C语言的相关知识,现在我们已经较为熟练的掌握了C语言中的各中代码语法和结构使用,能够使用代码来解决一些简单问题。但是对于一个程序员来说,仅仅会语法是远远不够的,从今天开始,我们将进入…...
案例描述:update中,MySQL inner join 和 left join的区别,小结果集驱动大结果集
场景描述 以一个场景为例: 单据A:下游子表 (数据量级小) 单据B:下游主表(数据量级小) 单据C:中游子表(数据量级小) 单据D:中游主表(…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
