1, 搭建标准的spring cloud 工程
这是一个 seata 的学习过程, 不强调使用, = _ = , 想速成的不建议看这个博客系列, 本博主放弃了可用性, 只保证了最终一致性.
1.1 未集成seata, 简单的远程调用,
1.2 业务需求, 注册用户赠送积分, 将对这一个业务流程进行分布式事务控制
1.3 工程目录
eureka // 注册中心
service-user // 微服务A, 用户服务
service-active // 微服务B, 积分服务
1.4 核心代码
/**
* 用户注册
*/
@GetMapping("/register")
public Object register(String name) {
String res = userService.addUser(name);
return res;
}
@Service
public class UserService {
@Transactional
public String addUser(String name) {
User user = userMapper.findByName(name);
if (user == null) {
user = new User();
user.setCreated(new Date());
user.setName(name);
userMapper.saveUser(user);
// Feign 调用积分服务
return activeFeignService.register(user.getName());
}
return "SUCCESS";
}
}
@RestController
@RequestMapping("/api/point")
public class PointController {
/**
* 注册赠送积分活动
* @param username 用户名称
* @return
*/
@RequestMapping("/register")
public String register(@RequestParam(name = "username") String username) {
// 新增积分账户
pointService.registerGivePoint(username);
return "SUCCESS";
}
}
@Service
public class PointService {
@Transactional
public void registerGivePoint(String username) {
PointAccount pointAccount = pointMapper.findByName(username);
if (pointAccount == null) {
pointAccount = new PointAccount();
pointAccount.setCreated(new Date());
pointAccount.setName(username);
pointAccount.setPoint(1);
pointMapper.createdAccount(pointAccount);
}
}
}
1.5 当前业务流程
A 注册 => (feign调用) => B服务(增加积分) => 流程结束
A 和 B 都开启了自己的事务控制
1.6 百度云工程
链接:https://pan.baidu.com/s/1J81SzcIumk-ktgLLd0OqBQ
提取码:fod7
2, 当前业务流程问题
- A 和 B 都锁定了资源, 放弃了可用性, 强调了一致性
- A 和 B 没有统一的事务控制, 假如了 B 其实已经提交了事务, 因为网络波动导致, A 的异常抛出, A 的事务回滚, 当前工程既不能保证强一致性, 也没有高可用性
- A 服务的事务还没有提交, 此时 B 服务的事务无法看见 A 插入数据的数据, 这是因为事务的隔离性, 导致不可见, 我觉得有一部分的业务应该是要看见的, 也就是说, A 和 B 的调用算成一个事务
3, 带着问题去搞它
- seata 能保证我们多个事务一定是全部成功或者全部失败吗, 怎么保证的
- seata 是怎么打破我们同一个事务(A 和 B)内的可见性, 不同事务的隔离性