前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot - 实践阿里巴巴【Manager 层_通用业务处理层】

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

作者头像
小小工匠
发布2022-03-21 15:50:25
1.4K0
发布2022-03-21 15:50:25
举报
文章被收录于专栏:小工匠聊架构小工匠聊架构

文章目录

规范

对比传统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 传统写法

代码语言:javascript
复制
 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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-03-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 规范
  • 对比传统MVC
  • 小栗子
    • V1.0 传统写法
      • V2.0 引入Manager层
      • 源码
      相关产品与服务
      数据库
      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档