【springcloudAlibaba】Seata处理分布式事务

本文档展示了如何在Spring Cloud项目中使用Seata进行分布式事务管理,包括数据库表的创建、Seata的依赖配置、全局事务的注解使用,以及订单、库存、账户服务的模拟操作。通过Seata的@GlobalTransactional注解,确保了在分布式环境下的事务一致性。
摘要由CSDN通过智能技术生成

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


Seate:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
下载

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启动nacos,启动seate:


在这里插入图片描述
在这里插入图片描述

DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order` (
  `id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `user_id` BIGINT(11) DEFAULT NULL COMMENT '用户id',
	`product_id` BIGINT(11) DEFAULT NULL COMMENT '产品id',
	`count` INT(11) DEFAULT NULL COMMENT '数量',
  `money` DECIMAL(11,0) DEFAULT NULL COMMENT '金额',
  `status` INT(1) DEFAULT NULL COMMENT '订单状态:0:创建中;1:已完结',
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
DROP TABLE IF EXISTS `t_storage`;
CREATE TABLE `t_storage` (
  `id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `product_id` BIGINT(11) DEFAULT NULL COMMENT '产品',
  `total` int(11) DEFAULT NULL COMMENT '总库存',
  `used` int(11) DEFAULT NULL COMMENT '已用库存',
  `residue` int(11) DEFAULT NULL COMMENT '剩余库存'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
DROP TABLE IF EXISTS `t_account`;
CREATE TABLE `t_account` (
  `id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `user_id` BIGINT(11) DEFAULT NULL COMMENT '用户id',
  `total` DECIMAL(10,0) DEFAULT NULL COMMENT '总额度',
  `used` DECIMAL(10,0) DEFAULT NULL COMMENT '已用余额',
  `residue` DECIMAL(10,0) DEFAULT NULL COMMENT '剩余可用余额'
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    <dependencies>
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
        </dependency>
 
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <!--剔除 自带的 seata 版本-->
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-all</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 保证 版本吻合 -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>0.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
 
        <!--基础配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
</project>

在这里插入图片描述

server:
  port: 2003
 
spring:
  application:
    name: seata-account-service-2003
 
  cloud:
    alibaba:
      seata:
        # 自定义 事务组,要与 seata-server 中 对应. ,有时是 default
        tx-service-group: default
 
    nacos:
      discovery:
        server-addr: 114.215.173.88:8848
 
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://114.215.173.88:3306/seata_account
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource
 
feign:
  hystrix:
    enabled: false
 
logging:
  level:
    io:
      seata: info
 
mybatis:
  mapperLocations: classpath:mybatis/mapper/*.xml

在这里插入图片描述

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class OrderEntity {
 
    private Long id;
    private Long user_id;
    private Long product_id;
    private Integer count;
    private BigDecimal money;
    /**
     * 订单状态:0:创建中;1:已完结;
     */
    private Integer status;
 
}
@Mapper
public interface OrderDao {
 
    /**
     * 下订单
     */
    int createOrder(OrderEntity orderEntity);
 
    /**
     * 改 订单状态
     */
    int updateOrder(@Param(value = "userId") Long userId,
                    @Param(value = "status") Integer status);
 
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="com.cloud.dao.OrderDao">
 
    <resultMap id="BaseResultMap" type="com.cloud.entity.OrderEntity">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <result column="user_id" property="userId" jdbcType="BIGINT"/>
        <result column="product_Id" property="productId" jdbcType="BIGINT"/>
        <result column="count" property="count" jdbcType="INTEGER"/>
        <result column="money" property="money" jdbcType="DECIMAL"/>
        <result column="status" property="status" jdbcType="INTEGER"/>
    </resultMap>
 
    <insert id="createOrder" parameterType="com.cloud.entity.OrderEntity">
        INSERT INTO seata_order.t_order
            (user_id, product_id, count, money, status)
        VALUES (#{userId}, #{productId}, #{count}, #{money}, #{status});
    </insert>
 
    <update id="updateOrder">
        UPDATE t_order t
        SET t.status = #{status}
        WHERE t.user_id = #{userId};
    </update>
 
</mapper>
@RestController
public class OrderController {
 
    @Autowired
    private OrderService orderService;
 
    @ResponseBody
    @GetMapping(value = "/createOrder")
    public CommonResult createOrder(@RequestBody OrderEntity orderEntity) {
 
        int order = orderService.createOrder(orderEntity);
 
        return new CommonResult(200, String.valueOf(order));
    }
 
}
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
 
    @Autowired
    private OrderDao orderDao;
 
    @Autowired
    private AccountService accountService;
 
    @Autowired
    private StorageService storageService;
 
    @Override
    @GlobalTransactional(name = "createOrder", rollbackFor = {Exception.class})
    public int createOrder(OrderEntity orderEntity) {
        log.info("1  开始 新建订单");
        int order = orderDao.createOrder(orderEntity);
 
        log.info("2  库存,数量 做扣减");
        CommonResult commonResult = storageService.decreaseStorage(orderEntity.getProductId(), orderEntity.getCount());
 
        log.info("3  账户 余额 扣减");
        CommonResult commonResult1 = accountService.decreaseAccount(orderEntity.getUserId(), orderEntity.getMoney());
 
        log.info("4  订单状态 修改");
        int i = updateOrder(orderEntity.getUserId(), 1);
        log.info("-------" + orderEntity.toString());
 
        log.info("下订单 结束了");
 
        return order;
    }
 
    @Override
    public int updateOrder(Long userId, Integer status) {
        int i = orderDao.updateOrder(userId, status);
        return i;
    }
}

在这里插入图片描述

@EnableFeignClients
@EnableDiscoveryClient
@MapperScan(value = "com.cloud.dao")
@SpringBootApplication
public class SeataOrderService2001 {
 
    public static void main(String[] args) {
        SpringApplication.run(SeataOrderService2001.class, args);
    }
}

在这里插入图片描述

@Mapper
public interface StorageDao {
 
    int decreaseStorage(@Param(value = "productId") Long productId,
                        @Param(value = "count") Integer count);
 
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="com.cloud.dao.StorageDao">
 
    <update id="decreaseStorage">
        UPDATE t_storage t
        SET t.used = t.used + #{count},
            residue=residue - #{count}
        WHERE product_id = #{productId};
    </update>
 
</mapper>
@RestController
public class OrderController {
 
    @Autowired
    private OrderService orderService;
 
    @ResponseBody
    @GetMapping(value = "/createOrder")
    public CommonResult createOrder(@RequestBody OrderEntity orderEntity) {
 
        int order = orderService.createOrder(orderEntity);
 
        return new CommonResult(200, String.valueOf(order));
    }
 
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
 
    @Autowired
    private OrderDao orderDao;
 
    @Autowired
    private AccountService accountService;
 
    @Autowired
    private StorageService storageService;
 
    @Override
    @GlobalTransactional(name = "createOrder", rollbackFor = {Exception.class})
    public int createOrder(OrderEntity orderEntity) {
        log.info("1  开始 新建订单");
        int order = orderDao.createOrder(orderEntity);
 
        log.info("2  库存,数量 做扣减");
        CommonResult commonResult = storageService.decreaseStorage(orderEntity.getProductId(), orderEntity.getCount());
 
        log.info("3  账户 余额 扣减");
        CommonResult commonResult1 = accountService.decreaseAccount(orderEntity.getUserId(), orderEntity.getMoney());
 
        log.info("4  订单状态 修改");
        int i = updateOrder(orderEntity.getUserId(), 1);
        log.info("-------" + orderEntity.toString());
 
        log.info("下订单 结束了");
 
        return order;
    }
 
    @Override
    public int updateOrder(Long userId, Integer status) {
        int i = orderDao.updateOrder(userId, status);
        return i;
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr_树先森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值