前言
关于分布式事务概念 在本片章节就不详细说了 不了解的童鞋可以自行百度 本篇主要来说分布式事务中LCN框架的基本使用方式 本文很长 但是非常详细 花费您2小时时间 能够让自己学会分布式事务如何解决 是否值得
- DEMO获取 提取码:lmlh
开始
第一步
在我们的LCN中 有 发起方和参与方两种角色
下载事务管理器项目
我们需要下载LCN的tm(事务管理器)并配置
下载地址
或者直接执行如下命令 也好
git clone https://github.com/codingapi/tx-lcn.git & cd txlcn-tm
- 1
修改配置信息 tx-lcn-5.0.2.RELEASE\txlcn-tm\src\main\resources\application.properties
spring.application.name=tx-manager
server.port=7970
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.use-generated-keys=true
#tx-lcn.logger.enabled=true
# TxManager Host Ip
#tx-lcn.manager.host=127.0.0.1
# TxClient连接请求端口
#tx-lcn.manager.port=8070
# 心跳检测时间(ms)
#tx-lcn.manager.heart-time=15000
# 分布式事务执行总时间
#tx-lcn.manager.dtx-time=30000
#参数延迟删除时间单位ms
#tx-lcn.message.netty.attr-delay-time=10000
#tx-lcn.manager.concurrent-level=128
# 开启日志
#tx-lcn.logger.enabled=true
#logging.level.com.codingapi=debug
#redis 主机
#spring.redis.host=127.0.0.1
#redis 端口
#spring.redis.port=6379
#redis 密码
#spring.redis.password=
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
注意 事务管理器 需要使用到Redis 注意开启redis服务 注意修改数据源配置
事务管理器需要自己的数据库和数据库表 所以下面是执行SQL脚本
执行数据库脚本
/*
Navicat Premium Data Transfer
Source Server : local
Source Server Type : MySQL
Source Server Version : 100309
Source Host : localhost:3306
Source Schema : tx-manager
Target Server Type : MySQL
Target Server Version : 100309
File Encoding : 65001
Date: 29/12/2018 18:35:59
*/
CREATE DATABASE IF NOT EXISTS </span>tx<span class="token operator">-</span>manager<span class="token punctuation">
DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
USE </span>tx<span class="token operator">-</span>manager<span class="token punctuation">
;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
– ----------------------------
– Table structure for t_tx_exception
– ----------------------------
DROP TABLE IF EXISTS </span>t_tx_exception<span class="token punctuation">
;
CREATE TABLE </span>t_tx_exception<span class="token punctuation">
(
</span>id<span class="token punctuation">
bigint(20) NOT NULL AUTO_INCREMENT,
</span>group_id<span class="token punctuation">
varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
</span>unit_id<span class="token punctuation">
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
</span>mod_id<span class="token punctuation">
varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
</span>transaction_state<span class="token punctuation">
tinyint(4) NULL DEFAULT NULL,
</span>registrar<span class="token punctuation">
tinyint(4) NULL DEFAULT NULL,
</span>ex_state<span class="token punctuation">
tinyint(4) NULL DEFAULT NULL COMMENT ‘0 待处理 1已处理’,
</span>remark<span class="token punctuation">
varchar(10240) NULL DEFAULT NULL COMMENT ‘备注’,
</span>create_time<span class="token punctuation">
datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (</span>id<span class="token punctuation">
) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 967 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
同时这个数据库脚本在项目目录 tx-lcn-5.0.2.RELEASE\txlcn-tm\src\main\resources\tx-manager.sql中也可以获取到
创建完毕之后和修改完毕之后 编译构建
mvn clean package '-Dmaven.test.skip=true'
- 1
如果使用cmd执行mvn命令报错可以尝试使用以下git bash here 哦
运行
编译构建完毕之后运行项目
内也有Dockerfile构建镜像的启动方式 在 docker 文件夹下 这里就不细说了
进入到 target目录
java -jar txlcn-tm-5.0.2.RELEASE.jar
- 1
运行如果报错 jar中没有主清单属性
在pom.xml中加入如下配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
再次启动 之后访问
http://127.0.0.1:7970
默认密码是 codingapi
成功之后会看到如下界面
至此 事务管理器成功启动
第二步
创建程序测试所需数据库test-a
和 test-b
数据库自行创建
下面是表数据SQL脚本 将两个库
test_a_tx
CREATE TABLE `test_a_tx`(
id BIGINT(20) NOT NULL AUTO_INCREMENT,
money INT(10) DEFAULT NULL ,
USER VARCHAR(32) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB DEFAULT CHARSET =utf8 ROW_FORMAT=DYNAMIC
INSERT INTO test_a_tx (money,USER) VALUES (1000,“xiaoming”)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
test_b_tx
CREATE TABLE `test_b_tx`(
id BIGINT(20) NOT NULL AUTO_INCREMENT,
money INT(10) DEFAULT NULL ,
USER VARCHAR(32) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB DEFAULT CHARSET =utf8 ROW_FORMAT=DYNAMIC
INSERT INTO test_a_tx (money,USER) VALUES (1000,“xiaohong”)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
test_a_tx 数据
test_b_tx 数据
第三步
如果你没有学习过SpringBoot也不要紧 本文会一步一步带你构建项目
创建SpringCloud项目 开发工具这里使用 idea 去下载
我们使用idea创建一个springboot项目
选择Spring初始化器 然后点击next
编辑groupId和aftifactId jdk版本是8 maven作为构建工具 之后点击next
选择SpringBoot版本 2.1.7 单机next
单机 finish 完成 等待项目加载
pom.xml内容
如果你这里在创建项目的时候填写的和本文不一致 修改 groupId 和 artifactId 两个标签内的内容
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.7.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>top.liwenxiang</groupId> <artifactId>lcn-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>lcn-demo</name> <description>Demo project for Spring Boot</description>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>packaging</span><span class="token punctuation">></span></span>pom<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>packaging</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>properties</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>java.version</span><span class="token punctuation">></span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>java.version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>spring-cloud.version</span><span class="token punctuation">></span></span>Greenwich.SR2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>spring-cloud.version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>properties</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-actuator<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-thymeleaf<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-web<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.mybatis.spring.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>mybatis-spring-boot-starter<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.1.0<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.cloud<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-cloud-starter-consul-discovery<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.cloud<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-cloud-starter-consul-config<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.cloud<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-cloud-starter-openfeign<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-devtools<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>scope</span><span class="token punctuation">></span></span>runtime<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>scope</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>optional</span><span class="token punctuation">></span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>optional</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>mysql<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>mysql-connector-java<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>scope</span><span class="token punctuation">></span></span>runtime<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>scope</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.projectlombok<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>lombok<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>optional</span><span class="token punctuation">></span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>optional</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>scope</span><span class="token punctuation">></span></span>test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>scope</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencyManagement</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.cloud<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-cloud-dependencies<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>${spring-cloud.version}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>type</span><span class="token punctuation">></span></span>pom<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>type</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>scope</span><span class="token punctuation">></span></span>import<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>scope</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencyManagement</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>build</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-maven-plugin<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugin</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>plugins</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>build</span><span class="token punctuation">></span></span>
</project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
紧接着 我们创建两个服务模块
接下来的界面和刚刚创建项目是一样的 这次我们创建一个maven项目 选择maven 直接下一步
groupid保持不变 修改 artifactId 点击next 下一个面板直接 finish 完成
pom.xml 由于这里的父工程已经依赖了我们所需要的jar包 所以这里无需引入多余的jar
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>lcn-demo</artifactId> <groupId>top.liwenxiang</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>test_a<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>0.0.1-SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span>
</project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
在我们的java源码目录创建包
内容为
点击OK
新建我们的启动类 SpringBoot 呢 没有了繁杂的XML配置文件 内置TOMCAT 我们可以编写一个启动类来启动SpringBoot项目
点击OK
LcnApplication.java 文件内容
@SpringBootApplication 是一个SpringBoot 应用程序
@EnableFeignClients 开启Feign客户端
@EnableDiscoveryClient 开启服务注册能够扫描到本服务 这个可以使用任意的注册中心
@EnableEurekaClient 这个不适用 因为现在eureka已经进入维护阶段 使用这个注解就只能够使用eureka注册中心了
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class LcnApplication {
public static void main(String[] args) {
SpringApplication.run(LcnApplication.class,args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
新建配置文件 application.yml
点击OK
注册中心我们这里采用consul作为注册中心 同时它还可以当作配置中心
新建配置文件 bootstrap.yml 文件 这个配置文件会在application.yml 之前被加载
springBoot 配置文件加载顺序
bootstrap.properties > bootstrap.yml > application.properties > application.yml
创建方式同上 以下是内容 这里不创建此文件 直接在到 application.yml 里也是可以的 这里只是引出
这个知识点
如果这里的内容要放在 application.yml 中的话 直接复制 cloud 以及 以下内容到 application.yml 中的 spring下即可
spring:
cloud:
consul:
host: localhost
port: 8500
config:
enabled: true #false禁用Consul配置,默认true
format: YAML # 表示consul上面文件的格式 有四种 YAML PROPERTIES KEY-VALUE FILES
#data-key: configuration #表示consul上面的KEY值(或者说文件的名字) 默认是data
data-key: data #表示consul上面的KEY值(或者说文件的名字) 默认是data
#prefix设置配置值的基本文件夹
#defaultContext设置所有应用程序使用的文件夹名称
#profileSeparator设置用于使用配置文件在属性源中分隔配置文件名称的分隔符的值
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
安装consul
刚刚在上面已经把配置信息 添加上了但是我们还没有安装呢 我们来安装一下
安装Consul,找到适合你系统的包下载他.Consul打包为一个’Zip’文件 下载地址
下载后解开压缩包.拷贝Consul到你的PATH路径中,在Unix系统中~/bin和/usr/local/bin
是通常的安装目录.根据你是想为单个用户安装还是给整个系统安装来选择.
在Windows系统中有可以安装到%PATH%的路径中.
完成安装后,通过打开一个新终端窗口检查consul安装是否成功.
下载下来是一个 consul_1.2.1_windows_amd64.zip 的压缩包,解压是是一个 consul.exe 的执行文件
cd 到对应的目录下,使用 cmd 启动 Consul
通过执行 consul
你应该看到类似下面的输出 这里的执行指的是在cmd中执行
[root@dhcp-10-201-102-248 ~]# consul
usage: consul [--version] [--help] <command> [<args>]
Available commands are:
agent Runs a Consul agent
configtest Validate config file
event Fire a new event
exec Executes a command on Consul nodes
force-leave Forces a member of the cluster to enter the "left" state
info Provides debugging information for operators
join Tell Consul agent to join cluster
keygen Generates a new encryption key
keyring Manages gossip layer encryption keys
kv Interact with the key-value store
leave Gracefully leaves the Consul cluster and shuts down
lock Execute a command holding a lock
maint Controls node or service maintenance mode
members Lists the members of a Consul cluster
monitor Stream logs from a Consul agent
operator Provides cluster-level tools for Consul operators
reload Triggers the agent to reload configuration files
rtt Estimates network round trip time between nodes
snapshot Saves, restores and inspects snapshots of Consul server state
version Prints the Consul version
watch Watch for changes in Consul
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
启动
#cmd启动:
consul agent -dev
- 1
- 2
启动成功之后访问:http://localhost:8500,可以看到 Consul 的管理界面
我这里是已经注册进去一个服务了 你们这里应该没有test-a
这样就意味着我们的 Consul 服务启动成功了。
Consul 服务端
这个就是我们的具体项目了 通过添加依赖
第一个是健康检查 第二个是客户端依赖 者依赖在我们之前的依赖已经包含了 所以不需要重复导入 这里只是单独提出来告诉你们需要这两个依赖进行服务注册
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这个时候我们可以启动一下项目 看是否能够注册到consul中
进入上面的文件 运行
成功之后访问 http://localhost:8080/
出现以下界面 代表启动成功
刷新 consul 列表 出现 test-a 代表成功注册进去
到这里我们的服务注解就OK了 接着开始编写业务代码
在 包下面 创建如下 文件
Account 实体类 表示一下 实际没用到 但是还是要有实体类
内容
package top.liwenxiang.lcn;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
/**
- 实体类 但是没有用到此DEMO中
*/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Account {
private Integer id;
private Integer money;
private String user;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
AccountDao 就是数据访问层 直接和数据库打交道的
内容
package top.liwenxiang.lcn;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
@Mapper
public interface AccountDao {
<span class="token annotation punctuation">@Update</span><span class="token punctuation">(</span><span class="token string">"UPDATE test_a_tx SET money = money - #{money} WHERE user = #{user}"</span><span class="token punctuation">)</span>
<span class="token keyword">int</span> <span class="token function">update</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">"money"</span><span class="token punctuation">)</span> <span class="token keyword">int</span> money<span class="token punctuation">,</span> <span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">"user"</span><span class="token punctuation">)</span> String user<span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
AccountService 业务层接口定义
内容
package top.liwenxiang.lcn;
import org.springframework.beans.factory.annotation.Autowired;
public interface AccountService {
<span class="token comment">/**
* @param money 支付金额
* @param user 支付用户名称
* @return
*/</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">pay</span><span class="token punctuation">(</span><span class="token keyword">int</span> money<span class="token punctuation">,</span>String user<span class="token punctuation">)</span><span class="token punctuation">;</span>
}
AccountServiceImpl 业务层实现类
`内容`
<span class="token keyword">package</span> top<span class="token punctuation">.</span>liwenxiang<span class="token punctuation">.</span>lcn<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Autowired<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span>Service<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>transaction<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Transactional<span class="token punctuation">;</span>
<span class="token annotation punctuation">@Service</span>
<span class="token annotation punctuation">@Transactional</span><span class="token punctuation">(</span>readOnly <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AccountServiceImpl</span> <span class="token keyword">implements</span> <span class="token class-name">AccountService</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Autowired</span>
AccountDao accountDao<span class="token punctuation">;</span>
<span class="token comment">/**
* 支付金额 支付用户名称
*
* @param money
* @param user
* @return
*/</span>
<span class="token annotation punctuation">@Override</span>
<span class="token annotation punctuation">@Transactional</span><span class="token punctuation">(</span>readOnly <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">pay</span><span class="token punctuation">(</span><span class="token keyword">int</span> money<span class="token punctuation">,</span> String user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> accountDao<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span>money<span class="token punctuation">,</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
AccountController 控制器层
`内容`
```java
<span class="token keyword">package</span> top<span class="token punctuation">.</span>liwenxiang<span class="token punctuation">.</span>lcn<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Autowired<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>RequestMapping<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>RequestMethod<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>RestController<span class="token punctuation">;</span>
<span class="token annotation punctuation">@RestController</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"tx"</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AccountController</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Autowired</span>
AccountService accountService<span class="token punctuation">;</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"pay"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>method <span class="token operator">=</span> RequestMethod<span class="token punctuation">.</span>GET<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">pay</span><span class="token punctuation">(</span><span class="token keyword">int</span> money<span class="token punctuation">,</span>String user<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> accountService<span class="token punctuation">.</span><span class="token function">pay</span><span class="token punctuation">(</span>money<span class="token punctuation">,</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li></ul></pre>
<p>TestBClient 调取test-b服务接口 使用Feign实现<br>
现在还没有创建test-b服务所以还没有使用Feign</p>
<p><code>内容</code></p>
<pre class="prettyprint"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token keyword">package</span> top<span class="token punctuation">.</span>liwenxiang<span class="token punctuation">.</span>lcn<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">TestBClent</span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre>
<p>现在我们再次启动服务 访问 http://localhost:8080/tx/pay?money=100&user=xiaoming</p>
<p>去到数据库查看 是否money字段减去了100</p>
<p><img src="https://img-blog.csdnimg.cn/20190903034217835.png" alt="在这里插入图片描述"><br>
如果成功减去100 那么本地事务和数据库操作是没有问题的</p>
<p>在控制台可以看到类似信息</p>
<p><img src="https://img-blog.csdnimg.cn/20190903034340101.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDU3NjM5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<p>如果你看不到 在 application.yml 中加入以下配置 重试</p>
<pre class="prettyprint"><code class="prism language-yaml has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token key atrule">mybatis</span><span class="token punctuation">:</span>
<span class="token key atrule">configuration</span><span class="token punctuation">:</span>
<span class="token key atrule">log-impl</span><span class="token punctuation">:</span> org.apache.ibatis.logging.stdout.StdOutImpl
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li></ul></pre>
<p>操作成功后 页面返回1<br>
<img src="https://img-blog.csdnimg.cn/2019090303451480.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDU3NjM5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>
现在开始创建test-b服务 步骤和创建test-a一致 这里就省略了</p>
<p>记得名字不要错 尽量和教程一致</p>
<p><img src="https://img-blog.csdnimg.cn/20190903034718506.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDU3NjM5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<p>业务代码和文件看下图<br>
<img src="https://img-blog.csdnimg.cn/20190903035500360.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDU3NjM5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>
修改内容如下</p>
<p>application.yml</p>
<p>修改数据源</p>
<pre class="prettyprint"><code class="prism language-yaml has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"> <span class="token key atrule">datasource</span><span class="token punctuation">:</span>
<span class="token key atrule">url</span><span class="token punctuation">:</span> jdbc<span class="token punctuation">:</span>mysql<span class="token punctuation">:</span>//localhost<span class="token punctuation">:</span>3307/test<span class="token punctuation">-</span>b<span class="token punctuation">?</span>useUnicode=true<span class="token important">&characterEncoding</span>=utf<span class="token punctuation">-</span>8<span class="token important">&useSSL</span>=false
<span class="token key atrule">username</span><span class="token punctuation">:</span> root
<span class="token key atrule">password</span><span class="token punctuation">:</span> root
<span class="token comment"># MySQL 8.x: com.mysql.cj.jdbc.Driver</span>
<span class="token key atrule">driver-class-name</span><span class="token punctuation">:</span> com.mysql.jdbc.Driver
<span class="token key atrule">type</span><span class="token punctuation">:</span> com.alibaba.druid.pool.DruidDataSource
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li></ul></pre>
<p>修改 端口</p>
<pre class="prettyprint"><code class="prism language-yaml has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token key atrule">server</span><span class="token punctuation">:</span>
<span class="token key atrule">port</span> <span class="token punctuation">:</span> <span class="token number">8081</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li></ul></pre>
<p>修改AccountController , AccountService , AccountServiceImpl 中的方法名为 addMoney 并修改Controller的映射路径为addMoney</p>
<pre class="prettyprint"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"> <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"addMoney"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>method <span class="token operator">=</span> RequestMethod<span class="token punctuation">.</span>GET<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">addMoney</span><span class="token punctuation">(</span><span class="token keyword">int</span> money<span class="token punctuation">,</span>String user<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> accountService<span class="token punctuation">.</span><span class="token function">addMoney</span><span class="token punctuation">(</span>money<span class="token punctuation">,</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li></ul></pre>
<p>LcnApplication 中的 @EnableFeignClients 可以删掉 也可以留着</p>
<p>AccountDao 中修改 - 为 + 并修改表名称</p>
<pre class="prettyprint"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"> <span class="token annotation punctuation">@Update</span><span class="token punctuation">(</span><span class="token string">"UPDATE test_b_tx SET money = money + #{money} WHERE user = #{user}"</span><span class="token punctuation">)</span>
<span class="token keyword">int</span> <span class="token function">update</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">"money"</span><span class="token punctuation">)</span> <span class="token keyword">int</span> money<span class="token punctuation">,</span> <span class="token annotation punctuation">@Param</span><span class="token punctuation">(</span><span class="token string">"user"</span><span class="token punctuation">)</span> String user<span class="token punctuation">)</span><span class="token punctuation">;</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li></ul></pre>
<p>启动test-b服务测试本地事务是否有效</p>
<p>启动完毕访问</p>
<p>http://localhost:8081/tx/addMoney?money=100&user=xiaohong</p>
<p>页面返回1代表成功</p>
<p>去数据库看是否增加100金额</p>
<p>同时刷新consul 看到两个服务上线</p>
<p><img src="https://img-blog.csdnimg.cn/20190903041624553.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDU3NjM5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>
此时修改test_a项目中的TestBClient文件</p>
<pre class="prettyprint"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token keyword">package</span> top<span class="token punctuation">.</span>liwenxiang<span class="token punctuation">.</span>lcn<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>cloud<span class="token punctuation">.</span>openfeign<span class="token punctuation">.</span>FeignClient<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>RequestMapping<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>RequestMethod<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>RequestParam<span class="token punctuation">;</span>
<span class="token annotation punctuation">@FeignClient</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"test-b"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">TestBClent</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"/tx/addMoney"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>method <span class="token operator">=</span> RequestMethod<span class="token punctuation">.</span>GET<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">addMoney</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestParam</span> <span class="token keyword">int</span> money<span class="token punctuation">,</span><span class="token annotation punctuation">@RequestParam</span> String user<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li></ul></pre>
<p>并修改AccountServiceImpl为</p>
<pre class="prettyprint"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token keyword">package</span> top<span class="token punctuation">.</span>liwenxiang<span class="token punctuation">.</span>lcn<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Autowired<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span>Service<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>transaction<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Transactional<span class="token punctuation">;</span>
<span class="token annotation punctuation">@Service</span>
<span class="token annotation punctuation">@Transactional</span><span class="token punctuation">(</span>readOnly <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AccountServiceImpl</span> <span class="token keyword">implements</span> <span class="token class-name">AccountService</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Autowired</span>
AccountDao accountDao<span class="token punctuation">;</span>
<span class="token annotation punctuation">@Autowired</span>
TestBClent testBClent<span class="token punctuation">;</span>
<span class="token comment">/**
* 支付金额 支付用户名称
*
* @param money
* @param user
* @return
*/</span>
<span class="token annotation punctuation">@Override</span>
<span class="token annotation punctuation">@Transactional</span><span class="token punctuation">(</span>readOnly <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">pay</span><span class="token punctuation">(</span><span class="token keyword">int</span> money<span class="token punctuation">,</span> String user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
String testBUser <span class="token operator">=</span> <span class="token string">"xiaohong"</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> i <span class="token operator">=</span> testBClent<span class="token punctuation">.</span><span class="token function">addMoney</span><span class="token punctuation">(</span>money<span class="token punctuation">,</span> testBUser<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> accountDao<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span>money<span class="token punctuation">,</span>user<span class="token punctuation">)</span> <span class="token operator">+</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li></ul></pre>
<p>重新启动test-a服务 访问 http://localhost:8080/tx/pay?money=100&user=xiaoming</p>
<p>看到页面返回2代表成功 再去观察数据库是否进行对应的修改 <strong>test-a 减 test-b 加</strong></p>
<p>现在开始测试报错 体现本地事务的弊端 领会分布式事务的应用场景</p>
<p>修改AccountServiceImpl文件为</p>
<pre class="prettyprint"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token keyword">package</span> top<span class="token punctuation">.</span>liwenxiang<span class="token punctuation">.</span>lcn<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Autowired<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span>Service<span class="token punctuation">;</span>
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>transaction<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Transactional<span class="token punctuation">;</span>
<span class="token annotation punctuation">@Service</span>
<span class="token annotation punctuation">@Transactional</span><span class="token punctuation">(</span>readOnly <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AccountServiceImpl</span> <span class="token keyword">implements</span> <span class="token class-name">AccountService</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Autowired</span>
AccountDao accountDao<span class="token punctuation">;</span>
<span class="token annotation punctuation">@Autowired</span>
TestBClent testBClent<span class="token punctuation">;</span>
<span class="token comment">/**
* 支付金额 支付用户名称
*
* @param money
* @param user
* @return
*/</span>
<span class="token annotation punctuation">@Override</span>
<span class="token annotation punctuation">@Transactional</span><span class="token punctuation">(</span>readOnly <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">pay</span><span class="token punctuation">(</span><span class="token keyword">int</span> money<span class="token punctuation">,</span> String user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
String testBUser <span class="token operator">=</span> <span class="token string">"xiaohong"</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> i <span class="token operator">=</span> testBClent<span class="token punctuation">.</span><span class="token function">addMoney</span><span class="token punctuation">(</span>money<span class="token punctuation">,</span> testBUser<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 增加内容</span>
<span class="token keyword">int</span> o <span class="token operator">=</span> <span class="token number">2</span> <span class="token operator">/</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token comment">// 增加内容</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> accountDao<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span>money<span class="token punctuation">,</span>user<span class="token punctuation">)</span> <span class="token operator">+</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li></ul></pre>
<p>程序运行起来之后访问 http://localhost:8080/tx/pay?money=100&user=xiaoming</p>
<p>看到如下 界面</p>
<p><img src="https://img-blog.csdnimg.cn/20190903042332498.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDU3NjM5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>
然后去看数据库 test-a 金额改变 test-b 增加金额</p>
<p>这个时候是不是出现问题了呢 这就是分布式事务的应用场景 能够解决跨服务的数据库事务问题 也就是不同的jdbc链接所操作的数据源 那么就真正的使用LCN</p>
<blockquote>
<p>第四步</p>
</blockquote>
<p>加入依赖信息 test-a test-b 都要加</p>
<pre class="prettyprint"><code class="prism language-xml has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>com.codingapi.txlcn<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>txlcn-tc<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>5.0.2.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>com.codingapi.txlcn<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>txlcn-txmsg-netty<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>5.0.2.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li></ul></pre>
<p>我们直接加入到父工程中</p>
<p>在两个服务的启动类上添加如下注解 开启分布式事务</p>
<pre class="prettyprint"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token annotation punctuation">@EnableDistributedTransaction</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre>
<p>在业务方法上添加如下注解@LcnTransaction 或者 @LxcTransaction 两个服务都添加 采用切面的方式 在方法一开始 就会创建一个事务组 当调用到参与方的时候 是通过HTTP协议通信的 请求头中包含组ID 当发起方方法执行完毕之后 事务协调者会告诉参与方可以提交了 在之前 参与方会有假提交操作</p>
<pre class="prettyprint"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;">@LcnTransaction //分布式事务注解
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre>
<p>重新启动两个服务 在去测试接口 http://localhost:8080/tx/pay?money=100&user=xiaoming</p>
<p>看到如下界面</p>
<p><img src="https://img-blog.csdnimg.cn/20190903044308873.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDU3NjM5,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>
这个时候如果你的数据库没有做任何改变 那么恭喜你 分布式事务已经生效了</p>
<p>如果你这个时候报错了 提示如下错误</p>
<p>No lcn connection when clear transaction</p>
<p>这个是很大可能性没有进到拦截器中所导致的错误 解决方法有如下几种(直接在官网搬的 学东西记得看官网)</p>
<p>确认Tx-client(TC)与Tx-manager™的版本是完全一致的。<br>
确认TC与TM的配置都没有问题,并确认TM是启动状态,可访问后台(默认密码:codingapi)。<br>
检测TM下TC在线模块是否正常对应。<br>
当以上都没有问题的时候,检查能否进入了DataSourceAspect的拦截,在开发工具的debug下环境下断点确认。<br>
若没有进入拦截器,可能存在两种情况。<br>
一:确认Datasource 是否为spring的bean对象,若非spring对象,请先处理成spring对象。<br>
二:若是spring对象,但是无法进入拦截。可以自行添加切面的方式进入拦截。<br>
该org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection方法就不能进入DataSource的拦截,可自行添加如下所示:</p>
<pre class="prettyprint"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token annotation punctuation">@Component</span>
<span class="token annotation punctuation">@Aspect</span>
<span class="token annotation punctuation">@Slf4j</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">TomcatDataSourceAspect</span> <span class="token keyword">implements</span> <span class="token class-name">Ordered</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Autowired</span>
<span class="token keyword">private</span> DTXResourceWeaver dtxResourceWeaver<span class="token punctuation">;</span><span class="token comment">//TX-LCN 资源切面处理对象</span>
<span class="token annotation punctuation">@Around</span><span class="token punctuation">(</span><span class="token string">"execution(public java.sql.Connection org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(..) )"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> Object <span class="token function">around</span><span class="token punctuation">(</span>ProceedingJoinPoint point<span class="token punctuation">)</span> <span class="token keyword">throws</span> Throwable <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"proxy my aspect.."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> dtxResourceWeaver<span class="token punctuation">.</span><span class="token function">getConnection</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span> <span class="token punctuation">(</span>Connection<span class="token punctuation">)</span> point<span class="token punctuation">.</span><span class="token function">proceed</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getOrder</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li></ul></pre>
<h4><a id="_934"></a>其他说明</h4>
<p>可选配置 application.yml</p>
<p>默认之配置为TM的本机默认端口</p>
<pre class="prettyprint"><code class="prism language-shell has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;">tx-lcn.client.manager-address<span class="token operator">=</span>127.0.0.1:8070
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre>
<p>其他配置</p>
<p>TM(事务管理器) 配置</p>
<pre class="prettyprint"><code class="prism language-properties has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;">spring.application.name=TransactionManager
server.port=7970
# JDBC 数据库配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
# 数据库方言
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
# 第一次运行可以设置为: create, 为TM创建持久化数据库表
spring.jpa.hibernate.ddl-auto=validate
# TM监听IP. 默认为 127.0.0.1
tx-lcn.manager.host=127.0.0.1
# TM监听Socket端口. 默认为 ${server.port} - 100
tx-lcn.manager.port=8070
# 心跳检测时间(ms). 默认为 300000
tx-lcn.manager.heart-time=300000
# 分布式事务执行总时间(ms). 默认为36000
tx-lcn.manager.dtx-time=8000
# 参数延迟删除时间单位ms 默认为dtx-time值
tx-lcn.message.netty.attr-delay-time=${tx-lcn.manager.dtx-time}
# 事务处理并发等级. 默认为机器逻辑核心数5倍
tx-lcn.manager.concurrent-level=160
# TM后台登陆密码,默认值为codingapi
tx-lcn.manager.admin-key=codingapi
# 分布式事务锁超时时间 默认为-1,当-1时会用tx-lcn.manager.dtx-time的时间
tx-lcn.manager.dtx-lock-time=${tx-lcn.manager.dtx-time}
# 雪花算法的sequence位长度,默认为12位.
tx-lcn.manager.seq-len=12
# 异常回调开关。开启时请制定ex-url
tx-lcn.manager.ex-url-enabled=false
# 事务异常通知(任何http协议地址。未指定协议时,为TM提供内置功能接口)。默认是邮件通知
tx-lcn.manager.ex-url=/provider/email-to/***@**.com
# 开启日志,默认为false
tx-lcn.logger.enabled=true
tx-lcn.logger.enabled=false
tx-lcn.logger.driver-class-name=${spring.datasource.driver-class-name}
tx-lcn.logger.jdbc-url=${spring.datasource.url}
tx-lcn.logger.username=${spring.datasource.username}
tx-lcn.logger.password=${spring.datasource.password}
# redis 的设置信息. 线上请用Redis Cluster
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li></ul></pre>
<p>TC(事务客户端) 配置</p>
<pre class="prettyprint"><code class="prism language-yaml has-numbering" οnclick="mdcp.copyCode(event)" style="position: unset;"><span class="token comment"># 是否启动LCN负载均衡策略(优化选项,开启与否,功能不受影响)</span>
tx<span class="token punctuation">-</span>lcn.ribbon.loadbalancer.dtx.enabled=true
<span class="token comment"># tx-manager 的配置地址,可以指定TM集群中的任何一个或多个地址</span>
<span class="token comment"># tx-manager 下集群策略,每个TC都会从始至终<断线重连>与TM集群保持集群大小个连接。</span>
<span class="token comment"># TM方,每有TM进入集群,会找到所有TC并通知其与新TM建立连接。</span>
<span class="token comment"># TC方,启动时按配置与集群建立连接,成功后,会再与集群协商,查询集群大小并保持与所有TM的连接</span>
tx<span class="token punctuation">-</span>lcn.client.manager<span class="token punctuation">-</span>address=127.0.0.1<span class="token punctuation">:</span><span class="token number">8070</span>
<span class="token comment"># 该参数是分布式事务框架存储的业务切面信息。采用的是h2数据库。绝对路径。该参数默认的值为{user.dir}/.txlcn/{application.name}-{application.port}</span>
tx<span class="token punctuation">-</span>lcn.aspect.log.file<span class="token punctuation">-</span>path=logs/.txlcn/demo<span class="token punctuation">-</span><span class="token number">8080</span>
<span class="token comment"># 调用链长度等级,默认值为3(优化选项。系统中每个请求大致调用链平均长度,估算值。)</span>
tx<span class="token punctuation">-</span>lcn.client.chain<span class="token punctuation">-</span>level=3
<span class="token comment"># 该参数为tc与tm通讯时的最大超时时间,单位ms。该参数不需要配置会在连接初始化时由tm返回。</span>
tx<span class="token punctuation">-</span>lcn.client.tm<span class="token punctuation">-</span>rpc<span class="token punctuation">-</span>timeout=2000
<span class="token comment"># 该参数为分布式事务的最大时间,单位ms。该参数不允许TC方配置,会在连接初始化时由tm返回。</span>
tx<span class="token punctuation">-</span>lcn.client.dtx<span class="token punctuation">-</span>time=8000
<span class="token comment"># 该参数为雪花算法的机器编号,所有TC不能相同。该参数不允许配置,会在连接初始化时由tm返回。</span>
tx<span class="token punctuation">-</span>lcn.client.machine<span class="token punctuation">-</span>id=1
<span class="token comment"># 该参数为事务方法注解切面的orderNumber,默认值为0.</span>
tx<span class="token punctuation">-</span>lcn.client.dtx<span class="token punctuation">-</span>aspect<span class="token punctuation">-</span>order=0
<span class="token comment"># 该参数为事务连接资源方法切面的orderNumber,默认值为0.</span>
tx<span class="token punctuation">-</span>lcn.client.resource<span class="token punctuation">-</span>order=0
<span class="token comment"># 是否开启日志记录。当开启以后需要配置对应logger的数据库连接配置信息。</span>
tx<span class="token punctuation">-</span>lcn.logger.enabled=false
tx<span class="token punctuation">-</span>lcn.logger.driver<span class="token punctuation">-</span>class<span class="token punctuation">-</span>name=$<span class="token punctuation">{</span>spring.datasource.driver<span class="token punctuation">-</span>class<span class="token punctuation">-</span>name<span class="token punctuation">}</span>
tx<span class="token punctuation">-</span>lcn.logger.jdbc<span class="token punctuation">-</span>url=$<span class="token punctuation">{</span>spring.datasource.url<span class="token punctuation">}</span>
tx<span class="token punctuation">-</span>lcn.logger.username=$<span class="token punctuation">{</span>spring.datasource.username<span class="token punctuation">}</span>
tx<span class="token punctuation">-</span>lcn.logger.password=$<span class="token punctuation">{</span>spring.datasource.password<span class="token punctuation">}</span>
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li></ul></pre>
<h2><a name="t1"></a><a name="t1"></a><a id="_1053"></a>结语</h2>
<p>到此为止 这个DEMO就完了 应该能够实现基本的分布式事务解决方案了吧~ 博主辛辛苦苦边敲编写 真实辛苦啦 写了三个小时这一篇文章 !!</p>
</div><div><div></div></div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
<div class="more-toolbox">
<div class="left-toolbox">
<ul class="toolbox-list">
<li class="tool-item tool-active is-like tool-clicked"><a href="javascript:;"><svg class="icon" aria-hidden="true">
<use xlink:href="#csdnc-thumbsup"></use>
</svg><span class="name">点赞</span>
<span class="count">1</span>
</a></li>
<li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true">
<use xlink:href="#icon-csdnc-Collection-G"></use>
</svg><span class="name">收藏</span></a></li>
<li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{"mod":"1582594662_002"}"><svg class="icon" aria-hidden="true">
<use xlink:href="#icon-csdnc-fenxiang"></use>
</svg>分享</a></li>
<!--打赏开始-->
<!--打赏结束-->
<li class="tool-item tool-more">
<a>
<svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
</a>
<ul class="more-box">
<li class="item"><a class="article-report">文章举报</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="person-messagebox">
<div class="left-message"><a href="https://blog.csdn.net/qq_39057639">
<img src="https://profile.csdnimg.cn/A/8/C/3_qq_39057639" class="avatar_pic" username="qq_39057639">
<img src="https://g.csdnimg.cn/static/user-reg-year/1x/3.png" class="user-years">
</a></div>
<div class="middle-message">
<div class="title"><span class="tit"><a href="https://blog.csdn.net/qq_39057639" data-report-click="{"mod":"popu_379"}" target="_blank">l w x 5 2 1</a></span>
</div>
<div class="text"><span>发布了119 篇原创文章</span> · <span>获赞 8</span> · <span>访问量 1万+</span></div>
</div>
<div class="right-message">
<a href="https://im.csdn.net/im/main.html?userName=qq_39057639" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
</a>
<a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a>
</div>
</div>
</div>