点击上方蓝色字体,选择“标星公众号”
优质文章,第一时间送达
上一篇:这300G的Java资料是我师傅当年给我的,免费分享给大家
下一篇:这200G的Java实战资料是我师傅当年教我的第二招
作者:怦然丶心动
来源:www.cnblogs.com/dousnl/p/9772632.html
参考官方地址:
https://github.com/codingapi/tx-lcn/wiki/TxManager%E5%90%AF%E5%8A%A8%E8%AF%B4%E6%98%8E
LCN事务控制原理是由事务模块TxClient下的代理连接池与TxManager的协调配合完成的事务协调控制。
TxClient的代理连接池实现了javax.sql.DataSource接口,并重写了close方法,事务模块在提交关闭以后TxClient连接池将执行"假关闭"操作,等待TxManager协调完成事务以后在关闭连接。
tx-manager 4.1.0
4.1.0
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.1.1
com.codingapi
transaction-springcloud
${lcn.last.version}
org.slf4j
*
com.codingapi
tx-plugins-db
${lcn.last.version}
org.slf4j
*
#Ribbon的负载均衡策略:随机
#ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
#由于springcloud默认是开启的重试机制,开启次机制以后会导致当springcloud请求超时时会重复调用业务模块,从而会引发数据混乱,因此建议将其禁用。对于网络模块超时等故障问题建议使用hytrix方式。
#ribbon.MaxAutoRetriesNextServer=0
tm:
manager:
url: http://localhost:8899/tx/manager/
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
MaxAutoRetriesNextServer: 0
init-db:true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000
package com.svw.tbox.tcloud.commons.ms.service;
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;
}
}
package com.svw.tbox.tcloud.commons.ms.service;
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;
}
}
import javax.sql.DataSource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.env.Environment;
import com.alibaba.druid.pool.DruidDataSource;
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@MapperScan(basePackages = "com.svw.tbox.tcloud.commons.ms.dao")
@ComponentScan(basePackages = { "com.svw.tbox.tcloud" })
publicclass MsApplication {
……
@Autowired
private Environment env;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));//用户名
dataSource.setPassword(env.getProperty("spring.datasource.password"));//密码
dataSource.setInitialSize(2);
dataSource.setMaxActive(20);
dataSource.setMinIdle(0);
dataSource.setMaxWait(60000);
dataSource.setValidationQuery("SELECT 1");
dataSource.setTestOnBorrow(false);
dataSource.setTestWhileIdle(true);
dataSource.setPoolPreparedStatements(false);
returndataSource;
}
调用方tcloud-mds => 参与方tcloud-commons
package com.svw.tbox.tcloud.commons.api.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import com.svw.tbox.tcloud.commons.api.config.TxFeignConfiguration;
import com.svw.tbox.tcloud.commons.api.service.SysErrorCodeMappingService;
/**
* ClassName: SysErrorCodeMappingFeign
* Description: 远程调用错误码服务
* Author: hurf
* Date: 2017年12月11日
*/
@FeignClient(value = "tcloud-commons-ms")
publicinterface SysErrorCodeMappingFeign extends SysErrorCodeMappingService {
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.codingapi.tx.annotation.TxTransaction;
import com.svw.tbox.tcloud.commons.api.entity.SysErrorCodeMapping;
import com.svw.tbox.tcloud.commons.api.feign.SysErrorCodeMappingFeign;
import com.svw.tbox.tcloud.commons.api.service.CmnService;
import com.svw.tbox.tcloud.commons.api.service.JedisTemplate;
import com.svw.tbox.tcloud.commons.util.DateUtil;
import com.svw.tbox.tcloud.mds.entity.ThUserLogin;
/**
* @TitleClassName: UserTokenService
* @DescriptionDescription: 登录服务
* @AuthorAuthor: hurf
* @DateDate: 2018年2月6日
*/
@Service
publicclass UserTokenService extends CmnService{
@Autowired
private JedisTemplate jedisTemplate;
@Autowired
private SysErrorCodeMappingFeign sysErrorCodeMappingFeign;
@Transactional
@TxTransaction(isStart=true)
public String add(SysErrorCodeMapping sysErrorCodeMapping) {
// 远程调用新增
sysErrorCodeMappingFeign.add(sysErrorCodeMapping);
// 本地新增db
insertSelective(ThUserLogin.builder().accessToken(sysErrorCodeMapping.getApiCode())
.refreshToken(sysErrorCodeMapping.getInnerErrorCode()).createBy("测试事务").build());
//本地缓存事务
jedisTemplate.set("isStart", DateUtil.getNow());
// int ii = 1/0;//异常
return"测试分布式事务成功";
}
}
@RestController
publicclass SysErrorCodeMappingController implements SysErrorCodeMappingService {
@Autowired
private MsService msService;
@ApiOperation("添加错误码信息")
@Override
public SystemResponse add(@RequestBody SysErrorCodeMapping sysErrorCodeMapping) {
returnmsService.add(sysErrorCodeMapping);
}
。。。。。。
importcom.codingapi.tx.annotation.ITxTransaction;
@Service
@CacheConfig(cacheNames = "sys-code-resource")
publicclass MsService implements ITxTransaction{
@Autowired
private JedisTemplate jedisTemplate;
@Autowired
private SysErrorCodeMappingMapper sysErrorCodeMappingMapper;
/**
* Title: 事务参与方
* Description:
* @param sysErrorCodeMapping
* @return
*/
@Transactional
public SystemResponse add(SysErrorCodeMapping sysErrorCodeMapping) {
//db操作
sysErrorCodeMapping.setVersion(1);
sysErrorCodeMapping.setDelFlag(Short.valueOf("0"));
sysErrorCodeMapping.setCreatedBy("admin");
sysErrorCodeMapping.setCreateDate(new Date());
sysErrorCodeMappingMapper.insertSelective(sysErrorCodeMapping);
//redis操作
jedisTemplate.set("addTest"+DateUtil.getNow(),"tttttttttttttttttttttt");
return ResultUtil.success(refreshAll());
}
启动两个微服务,访问调用方接口
删除刚刚的测试数据,开启异常情况:
@Transactional
@TxTransaction(isStart=true)
public String add(SysErrorCodeMapping sysErrorCodeMapping) {
// 远程调用新增
sysErrorCodeMappingFeign.add(sysErrorCodeMapping);
// 本地新增db
insertSelective(ThUserLogin.builder().accessToken(sysErrorCodeMapping.getApiCode())
.refreshToken(sysErrorCodeMapping.getInnerErrorCode()).createBy("测试事务").build());
//本地缓存事务
jedisTemplate.set("isStart", DateUtil.getNow());
intii = 1/0;//异常
return"测试分布式事务成功";
}
发现mysql已经回滚了,但是redis没有回滚 =》 目前只支持db分布式事务。
说句题外话,springboot全家桶技术交流群可以加我微信,但是坑位有限哦,由于忙于工作,有时不能及时回复大家,请多包涵。
猜你喜欢1、去了一趟字节跳动,被怼了!2、Redis实战--使用Jedis实现百万数据秒级插入3、Spring Boot+Mybatis+Swagger2 环境搭建4、TCP/IP,http,socket,长连接,短连接5、使用Redis之前5个必须了解的事情6、Spring 体系常用项目一览7、史上最全的Nginx配置参数中文说明8、快速搭建ELK日志分析系统
强烈推荐一位大佬的公众号
好文章,我在看❤️