分布式事务 —— TxLnc
分布式事务 —— TxInc简介TX-LCN 主要有两个模块,Tx-Client(TC) Tx-Manager™. TC作为微服务下的依赖,TM是独立的服务(用于管理事务)。前言上述图片中包含两个事务,rpc事务(1.1.1 addMoney)与事务(1.1.4 create),在Start函数上有@Transactional注解,但它无法控制rpc事务,如果rpc事务出现问题,1.1....
·
文章目录
分布式事务 —— TxLnc
简介
TX-LCN 主要有两个模块,Tx-Client(TC) Tx-Manager™. TC作为微服务下的依赖,TM是独立的服务(用于管理事务)。
前言
上述图片中包含两个事务,rpc事务(1.1.1 addMoney
)与事务(1.1.4 create
),在Start函数上有@Transactional注解,但它无法控制rpc事务,如果rpc事务出现问题,1.1.4依然会执行,所以我们就需要对分布式事务一致性进行处理
。
- 函数代码如下
@Transactional
public String start(int money) {
String user = "xiaoming";
//此处调用Feign(RPC事务)
String status = bankBClient.addMoney(money, user);
if("success".equals(status)) {
Account account = new Account();
account.setMoney(money);
account.setUser(user);
//如果有错误,本地回滚,调用的feign无法回滚
int res = accountDao.update(account);
return res > 0 ? "success" : "error";
}
return "rpc error";
}
搭建环境
安装Tx-Manager
Tx-Manager(TM —— 事务管理端)
- 下载源码
git clone https://github.com/codingapi/tx-lcn.git
- 修改tm配置(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
#redisIp
spring.redis.host=127.0.0.1
#redis端口
spring.redis.port=6379
#redis密码
spring.redis.password=123456
在使用时,按照自己的配置修改(比如我Redis有密码就要设置下)
- 编译(txlcn-tm下)
mvn clean package '-Dmaven.test.skip=true'
- 启动
java -jar txlcn-tm-5.0.1.RELEASE.jar
- 访问 http://127.0.0.1:7970,并登陆
默认密码是:condingapi
Tx-Client(TC) 在实际开发中才会使用,通过maven,导入依赖,具体下面的实战会介绍。
实战
TxLnc支持4种事务:
-
@TxcTransaction
-
@TccTransaction
-
@TxTransaction
-
@LcnTransaction
使用LcnTransaction
创建数据库
模拟分布式事务,需要多个库
- 创建两个库(bank-a、bank-b),并且都要执行下面的sql。
创建数据并插入一条记录
CREATE TABLE t_bank(
id BIGINT(20) NOT NULL PRIMARY KEY AUTO_INCREMENT,
money INT(10) DEFAULT NULL ,
user VARCHAR(32) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
insert into t_bank(money,user) values(1000, 'xiaoming');
此时,bank-a和bank-b库都有一条相同的数据,通过GitHub导出下面项目,并根据README进行布署。
项目
- 地址
Txilnc-Demo - 简介
工程 | 端口 | 描述 |
---|---|---|
bank-a | 8090 | 先rpc调用bank-b服务,执行加money,然后回到bank-a执行减money |
bank-b | 8099 | 执行加money操作 |
bank-common | 工具类,导入tc,供bank-a、bank-b使用 |
关键知识点
- 导入tc(bank-common)
<dependencies>
<!-- 加入分布式事务基础依赖 -->
<dependency>
<groupId>com.codingapi.txlcn</groupId>
<artifactId>txlcn-tc</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<!-- 加入分布式事务基础依赖 -->
<dependency>
<groupId>com.codingapi.txlcn</groupId>
<artifactId>txlcn-txmsg-netty</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
</dependencies>
- 在bank-a、bank-b的启动类上添加注释(标记为分布式事务管理),如下bank-a启动类
...
@EnableDistributedTransaction
public class BankAApplication {
public static void main(String[] args) {
SpringApplication.run(BankAApplication.class, args);
}
}
- 具体实现上添加@LcnTransaction注解,如下bank-a/…/BankService.java
@LcnTransaction
@Transactional
public String start(int money) {
String user = "xiaoming";
//此处调用Feign
String status = bankBClient.addMoney(money, user);
if("success".equals(status)) {
Account account = new Account();
account.setMoney(money);
account.setUser(user);
//如果有错误,本地回滚,调用的feign无法回滚
int res = accountDao.update(account);
throw new RuntimeException("insert money error");
// return res > 0 ? "success" : "error";
}
return "rpc error";
}
当bank-a抛出异常时,rpc bank-b事务没有提交。
使用Spring Cloud Feign 熔断Hystrix获取到RPC Service错误信息后,再去调用另一个RPC Service的事务无法控制,即无法实现控制分布式事务的需求。
更多推荐
已为社区贡献2条内容
所有评论(0)