一个典型的后台软件系统的设计复盘——(三)打通任督二脉-context
武侠小说练功讲究打通任督二脉。程序设计练到一定程度也讲究打通任督二脉。好奇心强的同学可以搜搜“打通任督二脉有什么感觉”。
spring的任督二脉ApplicationContext
最经典的任督二脉莫过于java中spring中的ApplicationContext。用惯spring的都会觉得,这里是这个各种实例的起源。概念解释就不搬砖了,见官网 http://spring.io/understanding/application-context
于是乎,以前创建个jdbc需要 Class.forname() 一大堆反射出工厂类再 getConn() 得到个连接,现在只需要 context.getBean("配置名") 就能得到,还能有datasource各种实现以及高级的事务封装。而实际使用时更方便只需要个 @Autowired 。spring兴起之时大家都是在热议其实现了IoC控制反转原则,现在看来不仅如此,更重要的是,构造了整个bean管理体系BeanFactory,并用ApplicationContext打通了应用的任督二脉。
曾见过一个稍微复杂的应用,Oracle一主一从一物理从,可是稍微用起来就数据库连接数不足。排查原因竟是ApplicationContext新建了三处,也就是说相应的连接池创建了三个。这里延伸出另一个概念,叫容器。官方的说法是,BeanFactory就是一个容器,ApplicationContext则是前者的扩展,也是个容器。在这个容器里,任督二脉是打通的,bean是创建好的、管理好的、相应依赖关系是清晰的。但现在的应用服务器多种多样,比如spring容器、spring boot容器、tomcat容器、dubbo容器,想清楚它们之间是否打通,可以避免一些很幽灵的坑。
scoping和lifecycle-作用范围和生命周期
应用1能不能通过ApplicationContext访问到应用2的类或对象?正常情况下不可以,这就是作用范围。而生命周期,则是指对象什么时候创建什么时候销毁什么时候变换状态。
对这两个概念更好的理解是数据库事务。比如某用户账上有10元,操作1给他存入20元还没提交,操作2查询他当前账户余额,若两个操作在同个事务则查到结果为30元,若两个操作是不同事务则查到结果为10元,事务隔开了两者的作用范围。而操作1什么时候生效则是生命周期:开启事务-更新余额-提交数据库-成功关闭或失败回滚。
复盘业务场景的任督二脉
这里的场景是商品-订单-调度任务的打通。首先订单分汇总order和商品项detail,detail记录商品快照和批次也是很常识的。然后detail触发个调度任务job去执行。
然而job开始结束成功失败都应该回来通知订单啊。job-detail有关联,没毛病。
然后需求变更了,有的job是单个detail,有的job是若干detail。依然可以detail指向job,没毛病。
又需求变更了,完成一个detail会有若干个job。。。第一反应当然是多对多。可是要按订单列出哪批detail做完了,order-detail-job并group by job未免太绕,于是建了一层订单拆分detailGroup。然而,真实的需求是,商品按货架归集,货架1的是若干个detail一起做,货架2的是单个detail,又引入一层实体为detailByShelf。
场景是:对于货架1,detailByShelf近似于detailGroup。对于货架2,detailByShelf用于呈现,按货架列出详情;detailGroup仅有单个detail且用于job。
job要回来更新订单状态,通过detailGroup即可。查询要按货架列出,则查询detailByShelf即可。用detailGroup把job和detail串起来放进job execution context,任督二脉算是打通了。
然而需求并没有就这样停止。job会拆解成多个step,某些step会更新对应的detail。也就是说,step要和detail挂钩。然而特定的step是要更新整个detailGroup的状态的。。。
所以,更精细的设计是:step-step context根据不同类型挂钩不同的订单项-detail或detailGroup。而状态更新通知是:
step状态汇总到job
step状态更新到detailGroup或detail,都汇总到detailGroup
detail汇总到detailByShelf再汇总到order
如何验证这个任督二脉是否完整打通了呢?可以套三个场景。
1.step的状态(比job更精细)能更新到detail的所有层级。
2.某一步step正在执行,可以追踪到整个订单以及其中的哪一项,比如 step - detail/detailGroup - order。
3.按货架列出可以找到当前正在执行的是那一步以后,比如detailByShelf-detail-step-job
再者,哪些job是服务于同个detailGroup,也要能串起来。
所以,整个完整的打通是:
job-detailGroup,若干个调度任务来完成一批商品
step-detail和step-detailGroup,一个步骤操作对应的整批或这批中的一个商品项
至此,整个任督二脉算是打通了,任务可以找到对应订单或商品,订单商品可以找到对应任务和步骤。
整个场景非常混淆的两个点是:
1.detailByShelf只是查询场景要用,不能混入context。因为对于货架2,一个job只做一个detail项,detailByShelf根本不能表达相应的关系。
2.step什么时候关联detailGroup?不是整批或单个商品项的区别,而是这个step本身的不同。
如果问我,程序打通任督二脉是什么感觉?我会回答,应该是,程序中想要的关联信息都能取到,数据库中想要的信息用几个简单查询就能捞出来 的感觉吧。
一个典型的后台软件系统的设计复盘——(三)打通任督二脉-context的更多相关文章
- 一个典型的后台软件系统的设计复盘——(二)如何id一个事物
这个话题,可以从类与对象说起. Dog dog1 = new Dog(); 哪个是类,哪个是对象?这个问题搞不清楚,后面就无从说起了.然后两个程序员之间沟通说,那个狗有问题.除非两人很默契,不然另一人 ...
- Linux下一个简单的日志系统的设计及其C代码实现
1.概述 在大型软件系统中,为了监测软件运行状况及排查软件故障,一般都会要求软件程序在运行的过程中产生日志文件.在日志文件中存放程序流程中的一些重要信息, 包括:变量名称及其值.消息结构定义.函数返回 ...
- 推荐一个 Laravel admin 后台管理插件
如何优雅的写代码,我想是每位程序员的心声.自从15年初第一次接触 Laravel 4.2 开始,我就迷上使用 Laravel 框架了.我一直都想找个时间好好写写有关 Laravel 的使用文章,由浅入 ...
- Linux内核设计第三周——构造一个简单的Linux系统
Linux内核设计第三周 ——构造一个简单的Linux系统 一.知识点总结 计算机三个法宝: 存储程序计算机 函数调用堆栈 中断 操作系统两把宝剑: 中断上下文的切换 进程上下文的切换 linux内核 ...
- 使用PHP开发一个简单的后台接口(响应移动端的get请求和post请求)
写一个简单的后台,在接到app请求数据的时候,返回对应的内容: index.php文件如下: <?php $id = $_POST['id']; if($id==001){ echo json_ ...
- ExtJS是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端ajax框架。
ExtJS是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端ajax框架.
- Asp.NetMVC利用LigerUI搭建一个简单的后台管理详解(函登录验证)
上一篇 Asp.Net 中Grid详解两种方法使用LigerUI加载数据库数据填充数据分页 了解了LigerUI 中Grid的基本用法 现在结合上一篇的内容做一个简单的后台管理,当然也有前台的页面 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(二十)——Saga框架实现思路分享
今天这篇博文的主要目的是分享一下我设计Saga的实现思路来抛砖引玉,其实Saga本身非常的类似于一个简单的工作流体系,相比工作流不一样的部分在于它没有工作流的复杂逻辑处理机制(比如会签),没有条件分支 ...
- MVC实用构架设计(三)——EF-Code First(6):数据更新最佳实践
前言 最近在整理EntityFramework数据更新的代码,颇有体会,觉得有分享的价值,于是记录下来,让需要的人少走些弯路也是好的. 为方便起见,先创建一个控制台工程,使用using(var db ...
随机推荐
- oracle mybatis批量插入,无匹配找默认
批量插入<insert id="insertIndi" parameterType="java.util.HashMap" useGeneratedKey ...
- Bugfree安装与使用
第一步:下载XAMPP和bugfree http://www.bugfree.org.cn/ http://www.apachefriends.org/zh_cn/xampp.html 第二步:安装 ...
- 开启Unity项目中VS工程的属性面板
https://www.cnblogs.com/CodeGize/p/7859656.html Unity生成的VS工程一般是无法打开属性面板的.但是事实上,如果使用VS for unity,通过配置 ...
- java中四种引用类型(对象的强、软、弱和虚引用)
对象的强.软.弱和虚引用在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2 ...
- gulp入门详情
gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成:使用她,我们不仅可以很愉快的编写代码,而且大 ...
- Ubuntu17.10下编译Openjdk8u
一开始笔者用的系统和软件版本都是最新的,导致编译了好几次都失败,最后找到解决的办法,现在记录一下编译及解决的方法 避免以后忘记 所用操作系统 Ubuntu17.10 所用软件及版本 make 3.8. ...
- Spring学习笔记:jdbcTemplate和数据源配置
一.使用Spring框架jdbcTemplate实现数据库的增删改查 1.数据库 /* SQLyog Ultimate v8.32 MySQL - 5.7.19-log : Database - in ...
- Error:Execution failed for task ':xutils:mergeDebugAndroidTestResources'. > No slave process to proc
Error:Execution failed for task ':xutils:mergeDebugAndroidTestResources'. > No slave process to p ...
- 使用itext导出pdf
导出pdf这个功能是在工作中遇到的,写这个功能的时候遇到了不少的问题,比如中文乱码,不显示的问题,这些问题在我不断的测试,研究后都一一解决了. 第一步,先导入所需要的jar包 第一个jar包是用于解决 ...
- int btn = (Button) findViewById(View.getId());
int btn = (Button) findViewById(View.getId());//这句话中的btn不能用来和按钮键Button的id号去比较 如果想存储Button,可以这样做: Sta ...