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(TM —— 事务管理端)
git clone https://github.com/codingapi/tx-lcn.git
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有密码就要设置下)
mvn clean package '-Dmaven.test.skip=true'
java -jar txlcn-tm-5.0.1.RELEASE.jar
TxInc支持4种事务:
@TxcTransaction
@TccTransaction
@TxTransaction
@LcnTransaction
模拟分布式事务,需要多个库
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进行布署。
工程 | 端口 | 描述 |
---|---|---|
bank-a | 8090 | 先rpc调用bank-b服务,执行加money,然后回到bank-a执行减money |
bank-b | 8099 | 执行加money操作 |
bank-common | 工具类,导入tc,供bank-a、bank-b使用 |
<dependencies>
<dependency>
<groupId>com.codingapi.txlcngroupId>
<artifactId>txlcn-tcartifactId>
<version>5.0.1.RELEASEversion>
dependency>
<dependency>
<groupId>com.codingapi.txlcngroupId>
<artifactId>txlcn-txmsg-nettyartifactId>
<version>5.0.1.RELEASEversion>
dependency>
dependencies>
...
@EnableDistributedTransaction
public class BankAApplication {
public static void main(String[] args) {
SpringApplication.run(BankAApplication.class, args);
}
}
@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事务没有提交。