这个话题,可以从类与对象说起。

Dog dog1 = new Dog();

哪个是类,哪个是对象?这个问题搞不清楚,后面就无从说起了。然后两个程序员之间沟通说,那个狗有问题。除非两人很默契,不然另一人肯定要懵圈,是狗这个类有问题,还是狗的实例对象的属性有问题。由此引出了今天的话题:如何id一个事物。首先,这个事物是一个类型,还是这个类型中具体的一个对象。

再者,同一个东西,有不同的阶段不同的形态。

  比如,扎啤。从仓库里搬出来的时候是整桶的,销售的时候却是一扎一扎的。计算一扎的利润时,就要进行转换换算了。所以通常设计的时候会有:采购环节的形态,称之为产品;销售环节的形态,称之为商品;两者之间有一定的换算方式,用于转换数量,也用于计算价格(成本)。
  既然举例是食品类的,那么必定有另一个问题。某天发现卖出的一件商品过期了,如何追踪到这件商品是什么时候谁采购的、同批的还有哪些?这便是另一个维度的信息,批次与库存:店内这款商品共N+M个,其中过期这批的有N个,过期这批来自什么时候谁的采购,总共数量有N+M+L个,另外有L个散落在哪些店。当然了,这是个强调保质期强调批次的例子,有些品类的库存只需要记个数量,比如服装类,这一层也可以做薄,要看具体场景。
  有那么一个极端场景,下架商品(改状态)失败,事务等待超时。原因竟然是,订单请求太多太久,修改库存时锁定了商品记录,所以状态也改不了。那么问题来了,库存信息和状态信息是同个数据库表里同个记录?偷懒这么做,请求量一上来就扛不住了。为什么?因为动静要分离啊,高并发的信息和长事务的信息要尽量拆分开。商品名、商品分类这些描述信息,偶尔才改动一次,可以认为是静态的;状态(是否可见、是否可售)、价格这些信息,改动也不频繁,也可以认为是静态的;而库存信息是变动非常频繁的,是动态的。需要动静分离的场景,更典型的例子就是,库存和基础信息放同个表,批量导入改商品标语的一个长事务锁住了表,结果订单扣库存锁等待,严重影响了成交。所以,动静要分离。
  在库存和基础信息这个场景里,指的基本上是同个东西,就是这种商品(所以才可能放在同个数据库表)。另一种场景的动静分离,则并不是同个东西。比如顾客3天前买了A商品2件,当时单价1元,今天顾客要退货退款,但A商品单价涨到2元了,是否去取A商品当前价格去计算退款多少钱?显然不是。所以在这种场景下,商品的当前价格是动态的,时不时会浮动的;而某一刻交易的价格是静态的,是既成事实的。所以订单信息中还应记录着每个商品成交那一刻的价格,我们经常称之为商品快照。当然,这只是设计的基本思想,具体实现可以冗余在订单里,也可以是专门的商品快照表记录而订单直接引用商品快照。
  所以,即便是同一个东西,比如商品,也会有采购、销售等不同阶段,也会有基础信息、批次库存、历史快照等不同形态。它们已经是不同的实体,需要用不同的记录去id去唯一标识。

再者,同一个过程,有不同的颗粒度。

  完成一个订单,可能需要捡货-打包-送出等,且称之为step1-step2-step3,那么也需要一个颗粒度把“执行这次订单”这个事件给组织起来,且称之为message,异步消息投递嘛。单次投送的时刻和状态当然要有。问题是倘若一个订单拆分成若干次执行,如何表达这次订单执行完成了没?可以考虑多一层job的概念,即job与订单对应,job里的多个message表示多个拆分,message里的step表示具体执行的步骤。所以,如果要追踪订单现在执行到哪一步,可以通过job-message-step找到;反过来要追踪某一步失败影响到哪张单也不难。
  正常情况下,job这一层也不是必须的,状态和时间直接挂在订单上也不是不可以。但如果特殊场景呢?比如不只是订单,促销也会发起若干个消息投递。再比如,订单被取消了,要插队追加个撤销,有个job层级做标记,就好操作很多了。
回过头来看颗粒度。如何唯一识别一个订单任务?整个单的是job,这个单的拆分则是message,具体每个步骤则是step。那么,订单中某个项呢?必定是包含在某次拆分中。所以,message应该引用着一个订单拆分项,而step则应引用着若干个订单拆分项明细。如此,便可以追踪到订单中某个商品的进度了。(当然,还是要看具体场景,是不是需要拆分订单,是不是需要追踪某个商品的进度。)

最后,即便同一个对象,也不一定是同个事物

  比如,java JPA中的entity bean。一个新建的实体对象,save前后是完全不一样的。保存前只是个纯粹的java对象,而保存后则是跟数据库记录有绑定的实体对象。所以,把未保存的对象存到引用的字段里是会运行时报错的,比如product实体引用了品牌brand,品牌对象未保存(未绑定到数据库记录)时就存入product.setBrand(brand),运行时就会报错。
  而实体类和承载web接口返回的类,其实也不该是同一个。新手经常会遇到,在controller层报错找不到数据库连接,一轮排查后发现,实体之间的join使用了懒加载,而在controller层是没事务没数据库连接的。其实问题的症结在于,实体类实体对象不应该返回给controller层,应该返回的是定制好了的POJO、符合接口返回的普通的java对象。我们经常偷懒把实体对象返回给controller层,也不是不可以,但是用的时候心里要明白,这里拿到的对象已经不是同个东西了,这里已经没事务没数据库连接了。

  如果哪天又有同事找你看看那个是什么问题,不要犹豫,掀桌而起!那个是哪个啊?什么环境(生产还是测试)什么场景(用户行为)什么环节有什么现象啊?如何id一个事物都讲不清楚,前方绝壁有大坑。。。那就慷慨就义跳进去填吧~

转载于:https://www.cnblogs.com/syjkfind/p/6445113.html

一个典型的后台软件系统的设计复盘——(二)如何id一个事物相关推荐

  1. 一个.net的系统的AOP设计思路二——页面控件校验映射

    3)写页面控件校验映射.我们的基础是建立在验证控件的基础上的.配置文件如下: <?xml version="1.0" encoding="utf-8" ? ...

  2. 一个简单的监控系统的设计

    一个简单的监控系统的设计 # // // 为了实现上级需要一个监控的需求,设计一个小的监控系统,结构如下图. // 虽然是一个比较简单的功能,但是仍然对代码的结构的关系进行了设计,使其具备良好的可扩展 ...

  3. 2021年4月19日 深圳头条后台开发实习面试(二面)(含总结)

    title: 2021年4月19日 深圳头条后台开发实习面试(二面) tags: 面经 2021年4月19日 深圳头条后台开发实习面试(二面) 自我介绍 面试直接跟我讲你想让我问哪个方面的问题呢?(这 ...

  4. App 后台架构设计方案 设计思想与最佳实践

    CSDN 2016博客之星评选结果公布      [系列直播]零基础学习微信小程序!        "我的2016"主题征文活动     博客的神秘功能 App 后台架构设计方案 ...

  5. 手机软件系统测试用例设计大全

    一. 等价类分析法 二. 边界值分析 三. 错误猜测法 四. 判定表法 五. 流程分析方法 六. 正交试验设计法 七. 状态迁移法 等价类分析法 等价类划分方法针对手机状态大致可以归几个大类: 按键类 ...

  6. 基于单片机的嵌入式系统的典型的应用程序框架设计

    在单片机应用程序中,最常用.也是最简单的一种典型框架就是前后台系统,这种框架通常是由主函数里的大循环和一个或几个中断服务程序组成,本文主要讲这种典型框架设计问题. 前后台系统适用于一些程序流程简单.实 ...

  7. 00 如何设计一个秒杀系统——秒杀系统架构设计都有哪些关键点

    一.如何理解秒杀系统 秒杀系统其实主要解决两个问题,一个是并发读,一个是并发写.并发读的核心优化理念是尽量减少用户到服务端来"读"数据,或者让他们读更少的数据:并发写的处理原则也一 ...

  8. 一个推荐系统,实现完整的设计-在百度搜索关键词推荐案例

    在之前一篇博文中, 有同学在评论中问了个问题: 怎样解决因式分解带来的推荐冷门.热门关键词的问题. 在回答这个问题的时候, 想到了近几年在做搜索推荐系统的过程中, 学术界和工业界的一些差别. 正好近期 ...

  9. 网站后台管理界面设计的一些想法

    一.最常见的网站后台管理的界面布局 1.头部 2.菜单 3.主要工作区域 4.底部 二.工作区的交互设计 后台操作管理的主要工作区域在图示的区域3,古老的网站后台管理程序中,区域3被设计成一次只能展示 ...

最新文章

  1. nyoj 284 坦克大战 (优先队列)
  2. PHP5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总
  3. 阿里集团业务驱动的升级——Dubbo 3.0 的演进思路
  4. 【英语-刘晓艳-词汇】词汇06
  5. 图解TCPIP-传输层 UDP报文格式
  6. UnityShader18:立方体贴图(上)
  7. CSS3特效,跳动的心
  8. svm对未知数据的分类_SVM多分类之一对一与一对多
  9. 中国生物能源行业市场规模预测及未来战略规划建议报告2022-2028年
  10. jQuery版本升级踩坑大全
  11. bandicam的延迟问题和画质问题
  12. 登陆远程kvm_通过IPMI kvm控制台远程重装服务器系统
  13. 使用urllib发起请求- urlopen发起请求read/decode/getcode/info/geturl-post请求抽屉网
  14. android 自定义剪裁,Android自定义View实现照片裁剪框与照片裁剪功能
  15. java 京东秒杀系统_京东秒杀浪费坑位惩罚你可知道?
  16. Google浏览器被劫持解决方法
  17. java图片上传同时后台直接给MultipartFile对象添加图片水印或者文字水印,然后直接上传带水印的图片
  18. fiddler抓包指南(浏览器、app抓包及证书安装)
  19. C# Winform调用百度接口实现身份证文字识别教程完整版!!!(源码)
  20. itextpdf简单使用 制作豆瓣日志pdf

热门文章

  1. android 炫酷背景,炫酷-背景图垂直循环滚动登录页,Android RecyclerView实现
  2. vue里获取不到data_vue methods中取不到data值
  3. python 为什么用%格式化_Python中应该使用%还是format来格式化字符串?
  4. matlab optimvar
  5. 模拟信号与离散信号之间的频率关系(由模拟信号采样得到的离散信号)
  6. 4行代码搞定iframe高度自动变化,完美兼容(转)
  7. ORACLE时间函数(SYSDATE)深入理解
  8. Linux系统的启动流程以及做个小小的Linux
  9. php取得客户端信息类
  10. OSChina 周六乱弹 —— 这辈子最丢脸的事