原理图
使用nginx实现故障转移
代码实现
pom
<properties>
<lcn.last.version>4.1.0</lcn.last.version>
</properties>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.codingapi</groupId>
<artifactId>transaction-springcloud</artifactId>
<version>${lcn.last.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.codingapi</groupId>
<artifactId>tx-plugins-db</artifactId>
<version>${lcn.last.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
yml 每个服务多加如下依赖注意每个服务的端口号是不一样的哦!
如果使用nginx实现负载均衡只需要将如下的ip:port改成nginx反向代理的域名即可
tm:
manager:
url: http://localhost:8899/tx/manager/
TxManagerHttpRequestServiceImpl
import com.codingapi.tx.netty.service.TxManagerHttpRequestService;
import com.lorne.core.framework.utils.http.HttpUtils;
import org.springframework.stereotype.Service;
@Service
publicclass TxManagerHttpRequestServiceImpl implements TxManagerHttpRequestService{
@Override
public String httpGet(String url) {
//GET请求前
String res = HttpUtils.get(url);
//GET请求后
returnres;
}
@Override
public String httpPost(String url, String params) {
//POST请求前
String res = HttpUtils.post(url,params);
//POST请求后
returnres;
}
}
TxManagerTxUrlServiceImpl
import com.codingapi.tx.config.service.TxManagerTxUrlService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class TxManagerTxUrlServiceImpl implements TxManagerTxUrlService{
@Value("${tm.manager.url}")
private String url;
@Override
public String getTxUrl() {
//load tm.manager.url
return url;
}
}
发起调用方和参与方都要写如上代码,不写如上代码整合lcn启动微服务会抱错
- 测试代码
调用方tcloud-mds => 参与方tcloud-commons
SysErrorCodeMappingFeign 发起方代码
@FeignClient(value = "tcloud-commons-ms")
publicinterface SysErrorCodeMappingFeign extends SysErrorCodeMappingService {
}
UserTokenService 发起方
@Service
publicclass UserTokenService{
@Autowired
//feign客户端远程调用接口实例
private SysErrorCodeMappingFeign sysErrorCodeMappingFeign;
@Transactional
//isStart=true表示发起方,被调用方此处为false,默认为false可不标注
@TxTransaction(isStart=true)
public String add(SysErrorCodeMapping sysErrorCodeMapping) {
//如下均为伪代码
// feign客户端调用参与方服务
sysErrorCodeMappingFeign.update();//扣库存
//db操作
add();//新增订单数据
// int ii = 1/0;//异常 //测试只需抛个异常看是否事务都回滚,都回滚表示分布式事务解决完毕
return"测试分布式事务成功";
}
}
MsService 参与方
@Service
publicclass MsService implements ITxTransaction{
@Autowired
private SysErrorCodeMappingMapper sysErrorCodeMappingMapper;
@Transactional
//可默认不标识参与方
//@TxTransaction(isStart=false)
public SystemResponse update() {
//如下均为伪代码
//db操作
sysErrorCodeMappingMapper.update();//假设为扣库存
return ResultUtil.success(refreshAll());
}
测试
调用发起方接口测试即可
小知识
类似的分布式事务解决方案还有阿里的GTS分布式解决框架哦!
www.mayikt.com