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;
}
}