Skip to content

Commit d6f1ca6

Browse files
author
YunaiV
committed
增加 seata 服务
1 parent 9f807d2 commit d6f1ca6

File tree

28 files changed

+853
-4
lines changed

28 files changed

+853
-4
lines changed

lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/OrderServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public class OrderServiceImpl implements OrderService {
2727
@Autowired
2828
private ProductService productService;
2929

30-
@GlobalTransactional
3130
@Override
3231
@DS(value = "order-ds")
32+
@GlobalTransactional
3333
public Integer createOrder(Long userId, Long productId, Integer price) throws Exception {
3434
Integer amount = 1; // 购买数量,暂时设置为 1。
3535

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>2.2.2.RELEASE</version>
9+
<relativePath/> <!-- lookup parent from repository -->
10+
</parent>
11+
<modelVersion>4.0.0</modelVersion>
12+
13+
<artifactId>lab-52-seata-at-httpclient-demo-account-service</artifactId>
14+
15+
<dependencies>
16+
<!-- 实现对 Spring MVC 的自动化配置 -->
17+
<dependency>
18+
<groupId>org.springframework.boot</groupId>
19+
<artifactId>spring-boot-starter-web</artifactId>
20+
</dependency>
21+
22+
<!-- 实现对数据库连接池的自动化配置 -->
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot-starter-jdbc</artifactId>
26+
</dependency>
27+
<dependency> <!-- 本示例,我们使用 MySQL -->
28+
<groupId>mysql</groupId>
29+
<artifactId>mysql-connector-java</artifactId>
30+
<version>5.1.48</version>
31+
</dependency>
32+
33+
<!-- 实现对 MyBatis 的自动化配置 -->
34+
<dependency>
35+
<groupId>org.mybatis.spring.boot</groupId>
36+
<artifactId>mybatis-spring-boot-starter</artifactId>
37+
<version>2.1.2</version>
38+
</dependency>
39+
40+
<!-- 实现对 Seata 的自动化配置 -->
41+
<dependency>
42+
<groupId>io.seata</groupId>
43+
<artifactId>seata-spring-boot-starter</artifactId>
44+
<version>1.1.0</version>
45+
</dependency>
46+
<!-- 实现 Seata 对 HttpClient 的集成支持 -->
47+
<dependency>
48+
<groupId>io.seata</groupId>
49+
<artifactId>seata-http</artifactId>
50+
<version>1.1.0</version>
51+
</dependency>
52+
53+
<!-- Apache HttpClient 依赖 -->
54+
<dependency>
55+
<groupId>org.apache.httpcomponents</groupId>
56+
<artifactId>httpclient</artifactId>
57+
<version>4.5.8</version>
58+
</dependency>
59+
</dependencies>
60+
61+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package cn.iocoder.springboot.lab52.accountservice;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class AccountServiceApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(AccountServiceApplication.class, args);
11+
}
12+
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package cn.iocoder.springboot.lab52.accountservice.controller;
2+
3+
import cn.iocoder.springboot.lab52.accountservice.dto.AccountReduceBalanceDTO;
4+
import cn.iocoder.springboot.lab52.accountservice.service.AccountService;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.web.bind.annotation.PostMapping;
9+
import org.springframework.web.bind.annotation.RequestBody;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
@RestController
14+
@RequestMapping("/account")
15+
public class AccountController {
16+
17+
private Logger logger = LoggerFactory.getLogger(AccountController.class);
18+
19+
@Autowired
20+
private AccountService accountService;
21+
22+
@PostMapping("/reduce-balance")
23+
public Boolean reduceBalance(@RequestBody AccountReduceBalanceDTO accountReduceBalanceDTO) {
24+
logger.info("[reduceBalance] 收到减少余额请求, 用户:{}, 金额:{}", accountReduceBalanceDTO.getUserId(),
25+
accountReduceBalanceDTO.getPrice());
26+
try {
27+
accountService.reduceBalance(accountReduceBalanceDTO.getUserId(), accountReduceBalanceDTO.getPrice());
28+
// 正常扣除余额,返回 true
29+
return true;
30+
} catch (Exception e) {
31+
// 失败扣除余额,返回 false
32+
return false;
33+
}
34+
}
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package cn.iocoder.springboot.lab52.accountservice.dao;
2+
3+
4+
import org.apache.ibatis.annotations.Mapper;
5+
import org.apache.ibatis.annotations.Param;
6+
import org.apache.ibatis.annotations.Select;
7+
import org.apache.ibatis.annotations.Update;
8+
import org.springframework.stereotype.Repository;
9+
10+
@Mapper
11+
@Repository
12+
public interface AccountDao {
13+
14+
/**
15+
* 获取账户余额
16+
*
17+
* @param userId 用户 ID
18+
* @return 账户余额
19+
*/
20+
@Select("SELECT balance FROM account WHERE id = #{userId}")
21+
Integer getBalance(@Param("userId") Long userId);
22+
23+
/**
24+
* 扣减余额
25+
*
26+
* @param price 需要扣减的数目
27+
* @return 影响记录行数
28+
*/
29+
@Update("UPDATE account SET balance = balance - #{price} WHERE id = 1 AND balance >= ${price}")
30+
int reduceBalance(@Param("price") Integer price);
31+
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package cn.iocoder.springboot.lab52.accountservice.dto;
2+
3+
/**
4+
* 账户减少余额 DTO
5+
*/
6+
public class AccountReduceBalanceDTO {
7+
8+
/**
9+
* 用户编号
10+
*/
11+
private Long userId;
12+
13+
/**
14+
* 扣减金额
15+
*/
16+
private Integer price;
17+
18+
public Long getUserId() {
19+
return userId;
20+
}
21+
22+
public AccountReduceBalanceDTO setUserId(Long userId) {
23+
this.userId = userId;
24+
return this;
25+
}
26+
27+
public Integer getPrice() {
28+
return price;
29+
}
30+
31+
public AccountReduceBalanceDTO setPrice(Integer price) {
32+
this.price = price;
33+
return this;
34+
}
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package cn.iocoder.springboot.lab52.accountservice.service;
2+
3+
/**
4+
* 账户 Service
5+
*/
6+
public interface AccountService {
7+
8+
/**
9+
* 扣除余额
10+
*
11+
* @param userId 用户编号
12+
* @param price 扣减金额
13+
* @throws Exception 失败时抛出异常
14+
*/
15+
void reduceBalance(Long userId, Integer price) throws Exception;
16+
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package cn.iocoder.springboot.lab52.accountservice.service;
2+
3+
import cn.iocoder.springboot.lab52.accountservice.dao.AccountDao;
4+
import io.seata.core.context.RootContext;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.stereotype.Service;
9+
import org.springframework.transaction.annotation.Transactional;
10+
11+
@Service
12+
public class AccountServiceImpl implements AccountService {
13+
14+
private Logger logger = LoggerFactory.getLogger(getClass());
15+
16+
@Autowired
17+
private AccountDao accountDao;
18+
19+
@Override
20+
@Transactional // 开启新事物
21+
public void reduceBalance(Long userId, Integer price) throws Exception {
22+
logger.info("[reduceBalance] 当前 XID: {}", RootContext.getXID());
23+
24+
// 检查余额
25+
checkBalance(userId, price);
26+
27+
logger.info("[reduceBalance] 开始扣减用户 {} 余额", userId);
28+
// 扣除余额
29+
int updateCount = accountDao.reduceBalance(price);
30+
// 扣除成功
31+
if (updateCount == 0) {
32+
logger.warn("[reduceBalance] 扣除用户 {} 余额失败", userId);
33+
throw new Exception("余额不足");
34+
}
35+
logger.info("[reduceBalance] 扣除用户 {} 余额成功", userId);
36+
}
37+
38+
private void checkBalance(Long userId, Integer price) throws Exception {
39+
logger.info("[checkBalance] 检查用户 {} 余额", userId);
40+
Integer balance = accountDao.getBalance(userId);
41+
if (balance < price) {
42+
logger.warn("[checkBalance] 用户 {} 余额不足,当前余额:{}", userId, balance);
43+
throw new Exception("余额不足");
44+
}
45+
}
46+
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
server:
2+
port: 8083
3+
4+
spring:
5+
application:
6+
name: account-service
7+
8+
datasource:
9+
url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8
10+
driver-class-name: com.mysql.jdbc.Driver
11+
username: root
12+
password:
13+
14+
# Seata 配置项,对应 SeataProperties 类
15+
seata:
16+
application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name}
17+
tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名
18+
# 服务配置项,对应 ServiceProperties 类
19+
service:
20+
# 虚拟组和分组的映射
21+
vgroup-mapping:
22+
account-service-group: default
23+
# 分组和 Seata 服务的映射
24+
grouplist:
25+
default: 127.0.0.1:8091
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>2.2.2.RELEASE</version>
9+
<relativePath/> <!-- lookup parent from repository -->
10+
</parent>
11+
<modelVersion>4.0.0</modelVersion>
12+
13+
<artifactId>lab-52-seata-at-httpclient-demo-order-service</artifactId>
14+
15+
<dependencies>
16+
<!-- 实现对 Spring MVC 的自动化配置 -->
17+
<dependency>
18+
<groupId>org.springframework.boot</groupId>
19+
<artifactId>spring-boot-starter-web</artifactId>
20+
</dependency>
21+
22+
<!-- 实现对数据库连接池的自动化配置 -->
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot-starter-jdbc</artifactId>
26+
</dependency>
27+
<dependency> <!-- 本示例,我们使用 MySQL -->
28+
<groupId>mysql</groupId>
29+
<artifactId>mysql-connector-java</artifactId>
30+
<version>5.1.48</version>
31+
</dependency>
32+
33+
<!-- 实现对 MyBatis 的自动化配置 -->
34+
<dependency>
35+
<groupId>org.mybatis.spring.boot</groupId>
36+
<artifactId>mybatis-spring-boot-starter</artifactId>
37+
<version>2.1.2</version>
38+
</dependency>
39+
40+
<!-- 实现对 Seata 的自动化配置 -->
41+
<dependency>
42+
<groupId>io.seata</groupId>
43+
<artifactId>seata-spring-boot-starter</artifactId>
44+
<version>1.1.0</version>
45+
</dependency>
46+
<!-- 实现 Seata 对 HttpClient 的集成支持 -->
47+
<dependency>
48+
<groupId>io.seata</groupId>
49+
<artifactId>seata-http</artifactId>
50+
<version>1.1.0</version>
51+
</dependency>
52+
53+
<!-- Apache HttpClient 依赖 -->
54+
<dependency>
55+
<groupId>org.apache.httpcomponents</groupId>
56+
<artifactId>httpclient</artifactId>
57+
<version>4.5.8</version>
58+
</dependency>
59+
</dependencies>
60+
61+
</project>

0 commit comments

Comments
 (0)