前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >seata实现分布式事务

seata实现分布式事务

作者头像
阿超
发布2022-08-16 19:24:09
3540
发布2022-08-16 19:24:09
举报
文章被收录于专栏:快乐阿超

尽管世界和人生是坏透了,其中却有一件东西永远是好,那便是青春——显克维奇

首先是下载seata1.4.1

然后解压

先修改conf下的registry.conf

type改为nacos

image-20210314184336107
image-20210314184336107

进入bin

打开控制台运行seata-server.bat

然后在项目中引入依赖,记得需要分布式式事务的服务都要配置

代码语言:javascript
复制
<!--    seata 分布式事务    -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

配置类

代码语言:javascript
复制
package com.ruben.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Optional;

/**
 * @ClassName: SeataConfig
 * @Description: 我还没有写描述
 * @Date: 2021/3/14 0014 16:53
 * *
 * @author: <achao1441470436@gmail.com>
 * @version: 1.0
 * @since: JDK 1.8
 */
@Configuration
public class SeataConfig {


    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }

}

然后是项目中的配置文件

代码语言:javascript
复制
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: ruben
  config:
    type: file
    file:
      name: file.conf
  service:
    disable-global-transaction: false

如果之后启动一直报没配置disableGlobalTransaction

就需要新建一个file.confresources目录下

内容为

代码语言:javascript
复制
service{
    disableGlobalTransaction = false
}

接下来是编写两个接口

首先是调用方

controller

代码语言:javascript
复制
@RestController
@RequestMapping("user")
public class UserController {
    @Resource
    private UserService userService;
    
    @GetMapping("order")
    public AjaxJson order() {
        return userService.order();
    }
}

service

代码语言:javascript
复制
@Slf4j
@Service
public class UserServiceImpl implements UserService {
    
    @Resource
    private MpOrderMapper mpOrderMapper;
    @Resource
    private ConsumerService consumerService;
    
    @Override
    @Transactional
    @GlobalTransactional
    public AjaxJson order() {
        consumerService.dropWare();
        mpOrderMapper.insert(OrderPO.builder().id(1L).build());
        return AjaxJson.success();
    }
}

ConsumerService是使用feign远程调用另一个接口

代码语言:javascript
复制
package com.ruben.feign;

import com.ruben.pojo.dto.PageDTO;
import com.ruben.utils.AjaxJson;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;

@FeignClient("ruben-consumer")
public interface ConsumerService {

    @GetMapping("ware")
    AjaxJson dropWare();
}

MpOrderMappermybatis-plus调用数据库的方法

代码语言:javascript
复制
package com.ruben.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruben.pojo.po.OrderPO;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface MpOrderMapper extends BaseMapper<OrderPO> {
}

然后是调用的ruben-consumer

首先也是引入依赖

其次是配置

代码语言:javascript
复制
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: SEATA_GROUP
  config:
    type: file
    file:
      name: file.conf
  service:
    disable-global-transaction: false
代码语言:javascript
复制
package com.ruben.rubenproducerdemo.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Optional;

/**
 * @ClassName: SeataConfig
 * @Description: 我还没有写描述
 * @Date: 2021/3/14 0014 16:53
 * *
 * @author: <achao1441470436@gmail.com>
 * @version: 1.0
 * @since: JDK 1.8
 */
@Configuration
public class SeataConfig {


    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }

}

然后是接口

代码语言:javascript
复制
package com.ruben.rubenproducerdemo.controller;

import com.ruben.rubenproducerdemo.service.WareService;
import com.ruben.rubenproducerdemo.utils.AjaxJson;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @ClassName: WareController
 * @Description: 我还没有写描述
 * @Date: 2021/3/13 0013 22:10
 * *
 * @author: <achao1441470436@gmail.com>
 * @version: 1.0
 * @since: JDK 1.8
 */
@RestController
@RequestMapping("ware")
public class WareController {
    @Resource
    private WareService wareService;

    @GetMapping
    public AjaxJson dropWare() {
        return wareService.dropWare();
    }
}

service

代码语言:javascript
复制
package com.ruben.rubenproducerdemo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruben.dao.WareMapper;
import com.ruben.rubenproducerdemo.pojo.po.WarePO;
import com.ruben.rubenproducerdemo.service.WareService;
import com.ruben.rubenproducerdemo.utils.AjaxJson;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * @ClassName: WareServiceImpl
 * @Description: 我还没有写描述
 * @Date: 2021/3/13 0013 22:14
 * *
 * @author: <achao1441470436@gmail.com>
 * @version: 1.0
 * @since: JDK 1.8
 */
@Service
public class WareServiceImpl extends ServiceImpl<WareMapper, WarePO> implements WareService {

    @Override
    @Transactional
    public AjaxJson dropWare() {
        WarePO ware = this.getById("1");
        Optional.ofNullable(ware).map(WarePO::getWare).filter(w -> w <= 0).ifPresent(wi -> {
            throw new RuntimeException("卖光啦!");
        });
        Optional.ofNullable(ware).ifPresent(w -> this.updateById(WarePO.builder().id("1").ware(w.getWare() - 1).build()));
        return AjaxJson.success("成功");
    }
}

我们开始测试

往数据库放条数据

image-20210314185153412
image-20210314185153412

首次调用接口时可以看到订单生成并且库存成功扣减

image-20210314185243786
image-20210314185243786
image-20210314185247897
image-20210314185247897

第二次调用发现抛出异常并成功回滚库存服务

至此,成功使用了seata实现了分布式事务

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档