springboot整合shardingsphere和seata实现分布式事务的实践
作者:「已注销」 发布时间:2021-08-10 04:28:37
标签:springboot,shardingsphere,分布式事务
各个框架版本信息
springboot: 2.1.3
springcloud: Greenwich.RELEASE
seata: 1.0.0
shardingsphere:4.0.1
maven 依赖
<dependency>
<!--<groupId>io.shardingsphere</groupId>-->
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
</dependency>
<!--sharding-jdbc 4.0.0 以后版本不能加starter 会导致启动数据源冲突-->
<!--<dependency>-->
<!--<groupId>com.alibaba</groupId>-->
<!--<artifactId>druid-spring-boot-starter</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-transaction-base-seata-at</artifactId>
</dependency>
需要增加的切面类
@Component
@Aspect
@Slf4j
public class SeataTransactionalAspect {
@Before("execution(* com.XXX.dao.*.*(..))")
public void before(JoinPoint joinPoint) throws TransactionException {
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
log.info("拦截到需要分布式事务的方法," + method.getName());
if(StringUtils.startsWithAny(method.getName(),"insert","save"
,"update","delete")){
TransactionTypeHolder.set(TransactionType.BASE);
}
}
}
ProductServiceImpl代码
@Service
public class ProductServiceImpl implements ProductService {
@Resource
UserFeignClient userFeignClient;
@Resource
ProductDao productDao;
@Override
@GlobalTransactional(name="zhjy-product-tx-group",rollbackFor = Exception.class)
public void createProduct(Product product) {
productDao.insertProduct(product);
ProductDesc proDesc = new ProductDesc();
proDesc.setProductDesc(product.getProductDesc());
proDesc.setStoreId(product.getStoreId());
proDesc.setProductId(product.getProductId());
productDao.insertProductDesc(proDesc);
// if(product.getProductName().endsWith("5")){
// int i = 1/0;
// }
// int j = 1/0;
User user = new User();
user.setAge(product.getPrice().intValue());
user.setUserName(product.getProductName());
user.setRealName(product.getProductName());
String msg = userFeignClient.saveUser(user);
//由于开启了服务调用降级,所以需要统一返回错误码,根据错误码主动抛出异常,让seata回滚事务
if(msg.equals("新增用户失败")){
int i = 1/0;
}
}
}
UserFeignClient代码
@FeignClient(name="service-user",fallbackFactory =UserFeignClientFallbackFactory.class)
public interface UserFeignClient {
@GetMapping("/user/getUserById")
@ResponseBody
String getUserById(@RequestParam("id") Integer id);
@GetMapping("/user/getUserByIdWithPathVariable/{id}")
@ResponseBody
String getUserByIdWithPathVariable(@PathVariable("id") Integer id);
@PostMapping("/user/saveUser")
@ResponseBody
String saveUser(@RequestBody User user );
}
User服务 UserController代码
@RestController
@Slf4j
@RefreshScope
public class UserController {
@Autowired
UserService userService;
@PostMapping("/user/saveUser")
@ResponseBody
public String saveUser(@RequestBody User user) {
userService.saveUser(user.getUserName(),user.getRealName(),user.getAge());
// if(user.getAge()>5){
int i = 1/0;
// }
return "sucess";
}
}
UserServiceImpl代码
@Service
public class UserServiceImpl implements UserService {
@Resource
UserDao userDao;
@Override
public void saveUser(String userName, String realName, Integer age) {
userDao.insertUser(userName,realName,age);
}
}
来源:https://blog.csdn.net/weixin_47574208/article/details/105948175


猜你喜欢
- 前言我们知道,Java项目编译后会生成许许多多的class文件,class文件保存着类的描述信息。虚拟机把描述类的数据从Class文件加载到
- Spring Boot 简介spring框架功能很强大,但是就算是一个很简单的项目,我们也要配置很多东西。因此就有了Spring Boot框
- Filter过滤器和Listener * 详解Filter过滤器Filter的简介 对资源的访问进行过滤,相当于小区的保安,进去
- 本文主要介绍了Spring Boot 应用可视化监控,分享给大家,具体如下:1、Spring Boot 应用暴露监控指标【版本 1.5.7.
- C#是托管型代码,创建的对象会自动回收。C++是非托管型代码,创建的对象需要手动回收(有时不手动回收,可能出现内存溢出的问题)。C#调用C+
- zuul动态路由网关服务是流量的唯一入口。不能随便停服务。所以动态路由就显得尤为必要。数据库动态路由基于事件刷新机制热修改zuul的路由属性
- 我们都知道Android应用软件基本上都会用到登录注册功能,那么对一个一个好的登录注册模块进行封装就势在必行了。这里给大家介绍一下我的第一个
- 一、栈(Stack)1、什么是栈?栈其实就是一种数据结构 - 先进后出(先入栈的数据后出来,最先入栈的数据会被压入栈底)什么是java虚拟机
- (Memory Leak,内存泄漏)为什么会产生内存泄漏?当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致
- 在微信公众号支付的API中没有这个接口,如果企业需要给用户转账,或者让用户提现或者给用户发红包等需要再商户平台中的产品中心分别开通。一、开通
- PullToRefresh是一套实现非常好的下拉刷新库,它支持:1.ListView2.ExpandableListView3.GridVi
- 本文实例为大家分享了unity鼠标或者手指点击模型播放动的具体代码,供大家参考,具体内容如下using UnityEngine;using
- 目录截屏AudioRecord音频采集MediaCodec编码音频数据Rtp发送数据SDP文件配置音频config配置计算方式:vlc测试播
- System.out.print("\b") 会在控制台下往回删掉一个字符,如果你想回删多个字符就打印多个 "
- RocketMQ发送消息我们在使用RocketMQ发送消息时,一般都会使用DefaultMQProducer,类型的代码如下:Default
- 一、为什么要编码不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解
- 本文实例分析了java中成员变量与局部变量区别。分享给大家供大家参考。具体分析如下:成员变量:在这个类里定义的私有变量,属于这个类。创建以及
- 背景当一个项目分了很多模块,很多个服务的时候,一些公共的配置就需要统一管理了,于是就有了元数据驱动!简介什么是Calcite?是一款开源SQ
- 要想充分发挥ADO.NET的优势,不仅需要全面、深入理解ADO.NET编程模型,及时总结经验、技巧也十分重要。ADO已经有多年的实践经验,A
- 1.注解方式,yml文件配置上以下就可以直接使用mybatis-plus: mapper-locations: classpath:mapp