SpringBoot - 实践阿里巴巴【Manager 层_通用业务处理层】

简介: SpringBoot - 实践阿里巴巴【Manager 层_通用业务处理层】



规范


对比传统MVC

说几个弊端

  • Service层代码臃肿
  • Service层易出现大事务,事务嵌套,易出问题且难排查
  • dao层混杂业务逻辑
  • dao层sql语句复杂

为了解决这个问题,《阿里巴巴泰山版java开发手册》推荐在Service层之下独立出一个通用业务处理层(Manager层)

相比较传统的MVC,主要增加了 Manager 层, 它有如下特征:

  • 1) 对第三方平台封装的层,预处理返回结果及转化异常信息
  • 2) 对 Service 层通用能力的下沉,如缓存方案、中间件通用处理
  • 3) 与 DAO 层交互,对多个 DAO 的组合复用

实际开发中,

  • 对于复杂业务,service调用manager层,然后把事务下沉到Manager层,Manager层不允许相互调用,不会出现事务嵌套。
  • 专注于不带业务SQL,也可以在manager层进行通用业务的dao层封装。
  • 避免复杂的join查询,可以在manager层严格控制好SQL,应对复杂的SQL查询。

简言之, Manager 层提供原子服务接口,Service 层负责依据业务逻辑来调用原子接口。


小栗子

举个例子说明一下Manager层的使用场景

需求:

  1. APP 登录的用户,如果系统中没有用户,需要自动创建用户,然后再返回相关的用户信息用于展示
  2. 网页端登陆的用户,如果系统中没有用户,不自动创建用户,需要用户注册。

反手就是一顿突突啊


V1.0 传统写法

package com.artisan.service;
import com.artisan.dao.UserDao;
import com.artisan.response.ResponseData;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.concurrent.TimeUnit;
/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */
@Service
public class ServiceWithoutManager {
    private final boolean APP = true;
    @Autowired
    private UserDao userDao;
    @Transactional(rollbackFor = Throwable.class)
    public ResponseData<String> buiz(Long idCard, Long name) {
        // 验证 1  假设  DB操作 校验
        String  var1 = doDBCheck1();
        // 验证 2  假设  DB操作 校验
        String  var2 =  doDBCheck2();
        // 业务  APP -- DB校验 --- 自动创建用户 -- 返回用户信息
        //      网页 -- DB校验 ---  -- 返回用户信息
        doBiz(var1,var2);
        return ResponseData.success("success");
    }
    @SneakyThrows
    private void doBiz(String a ,String b) {
        if(APP) {
            // 模拟业务耗时
            TimeUnit.MILLISECONDS.sleep(1200);
        }else {
        }
    }
    @SneakyThrows
    private String doDBCheck2() {
        // 模拟业务耗时
        TimeUnit.MILLISECONDS.sleep(500);
        return "";
    }
    @SneakyThrows
    private String doDBCheck1() {
        // 模拟业务耗时
        TimeUnit.MILLISECONDS.sleep(1000);
        return "";
    }
}


这有啥子问题? 常规操作啊…

每日一博 - 常见的Spring事务失效&事务不回滚案例集锦

让我们来分析分析

  • 典型的长事务问题 , 由于方法上有@Transactional 注解,所以验证和业务都是使用的同一个 connection
  • 对于复杂业务、复杂的验证逻辑,会导致整个验证过程始终占用该 connection 连接,占用时间可能会很长,直至方法结束,connection 才会交还给数据库连接池。

对于复杂业务的不可预计的情况,长时间占用同一个 connection 连接应该尽量避免,应该尽量缩短占用时间。


@Transactional 注解, AOP 实现,本质就是在目标方法执行前后进行拦截。 在目标方法执行前加入或创建一个事务,在执行方法执行后,根据实际情况选择提交或是回滚事务。

当 Spring 遇到该注解时,会自动从数据库连接池中获取 connection,并开启事务然后绑定到 ThreadLocal 上,对于@Transactional注解包裹的整个方法都是使用同一个connection连接。

如果出现了耗时的操作,比如三方接口调用,业务逻辑复杂,大数据处理等就会导致占用这个connection的时间过长,数据库连接一直被占用不释放。一旦类似操作过多,进而导致数据库连接池耗尽。



V2.0 引入Manager层

将数据在 service 层准备好,然后传递给 manager 层,由 manager 层添加@Transactional事务注解进行数据库操作, 尽量减少大事务带来的危害。


源码

https://github.com/yangshangwei/boot2


相关文章
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
1018 0
|
9月前
|
JSON 前端开发 Java
深入理解 Spring Boot 中日期时间格式化:@DateTimeFormat 与 @JsonFormat 完整实践
在 Spring Boot 开发中,日期时间格式化是前后端交互的常见痛点。本文详细解析了 **@DateTimeFormat** 和 **@JsonFormat** 两个注解的用法,分别用于将前端传入的字符串解析为 Java 时间对象,以及将时间对象序列化为指定格式返回给前端。通过完整示例代码,展示了从数据接收、业务处理到结果返回的全流程,并总结了解决时区问题和全局配置的最佳实践,助你高效处理日期时间需求。
1242 0
|
9月前
|
存储 Java 数据库
Spring Boot 注册登录系统:问题总结与优化实践
在Spring Boot开发中,注册登录模块常面临数据库设计、密码加密、权限配置及用户体验等问题。本文以便利店销售系统为例,详细解析四大类问题:数据库字段约束(如默认值缺失)、密码加密(明文存储风险)、Spring Security配置(路径权限不当)以及表单交互(数据丢失与提示不足)。通过优化数据库结构、引入BCrypt加密、完善安全配置和改进用户交互,提供了一套全面的解决方案,助力开发者构建更 robust 的系统。
316 0
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
1122 2
|
9月前
|
JSON 前端开发 Java
深入理解 Spring Boot 中日期时间格式化:@DateTimeFormat 与 @JsonFormat 完整实践
在 Spring Boot 开发中,处理前后端日期交互是一个常见问题。本文通过 **@DateTimeFormat** 和 **@JsonFormat** 两个注解,详细讲解了如何解析前端传来的日期字符串以及以指定格式返回日期数据。文章从实际案例出发,结合代码演示两者的使用场景与注意事项,解决解析失败、时区偏差等问题,并提供全局配置与局部注解的实践经验。帮助开发者高效应对日期时间格式化需求,提升开发效率。
2811 2
|
XML Java UED
使用 Spring Boot 实现重试和补偿功能:从理论到实践
【6月更文挑战第17天】在分布式系统中,服务之间的调用可能会因为网络故障、服务器负载等原因偶尔失败。为了提高系统的可靠性和稳定性,我们经常需要实现重试和补偿功能。
832 6
|
11月前
|
前端开发 Java Nacos
🛡️Spring Boot 3 整合 Spring Cloud Gateway 工程实践
本文介绍了如何使用Spring Cloud Alibaba 2023.0.0.0技术栈构建微服务网关,以应对微服务架构中流量治理与安全管控的复杂性。通过一个包含鉴权服务、文件服务和主服务的项目,详细讲解了网关的整合与功能开发。首先,通过统一路由配置,将所有请求集中到网关进行管理;其次,实现了限流防刷功能,防止恶意刷接口;最后,添加了登录鉴权机制,确保用户身份验证。整个过程结合Nacos注册中心,确保服务注册与配置管理的高效性。通过这些实践,帮助开发者更好地理解和应用微服务网关。
1965 0
🛡️Spring Boot 3 整合 Spring Cloud Gateway 工程实践
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
774 5
|
安全 Java 数据安全/隐私保护
如何使用Spring Boot进行表单登录身份验证:从基础到实践
如何使用Spring Boot进行表单登录身份验证:从基础到实践
394 5
|
监控 Java 数据安全/隐私保护
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
756 5