企业应用架构模式

分层

  • 分层有利于标准化工作
  • 层次并不能封装所有东西,有时会带来级联修改
  • 过多的层级会影响性能
  • 分层架构中最困哪的问题是决定建立那些层次以及每一层职责是什么

组织领域逻辑

领域逻辑的组织可以分为三种主要的模式:事务脚本、领域模型以及表模块

  • 复杂逻辑情况的处理必然要引入对象,解决签署问题的面向对象方案是使用领域模型

  • 面向对象/领域模型你要考虑的是什么事情安排到什么类中

  • 做出抉择、做出决定。

  • 处理领域逻辑的常见方法是将领域再细分成两层:服务层独立出来,至于底层的领域模型或表模块之上,通常只有使用领域模型或表模块时才会这样细分。服务层是放置事务控制和安全等功能的好场所

  • 最小化情况下,服务层只是一个外观facade,所有实际行为都在下层对象中,服务层所做的只是将上层调用传递到更底层。用于增加事务封装和安全检查功能

并发

  • 并发控制不好会导致的问题:更新丢失和不一致读。如果可以任何原来那些基本问题,那么就可以避免任何形式的并发控制
  • 解决并发问题的解决方案:隔离性 (共享资源互斥)+ 不变性(读写分离,只读用拷贝的数据源)
  • 乐观并发控制和悲观并发控制 。这两种策略都存在问题,
    • 乐观锁:先用后解决冲突 => 冲突检测
    • 悲观锁:独占排他 => 冲突避免,对于悲观锁来说一个特别问题就是死锁。超时控制和检测机制处理已经出现的死锁,其他方法则是尽力防止死锁发生,虽然需要选择牺牲者,但总比因场景无法满足导致死锁现象发生
    • 在乐观锁和悲观锁之间进行选择的标准是:冲突的频率与严重性。如果冲突很少,或者冲突的后果不会很严重,那么通常情况下应该选择乐观锁,因为它能得到更好的并发性,而且更容易实现,但是冲突的结果对于用户来说是痛苦的,那么就需要使用悲观锁策略
  • 处理并发最主要工具就是事务,事务是一个有边界的工作序列,开始和结束都有明确定义。
    • ACID:原子性、一致性、隔离性、持久性
    • 尽可能保证事务比较短,不要让事务跨越多个请求
    • 数据紧张时,尽可能晚打开事务(不推荐),应在事务外完成独具数据操作,只在修改数据的时候启动事务。这样的做的好处减少了事务执行时间,但是也意味着事务启动之前没有任何并发控制机制,可能会导致不一致读问题
    • 使用事务时,需要清除的知道被锁住的到底是什么,对于许多数据库操作来说,事务系统锁住的是被访问的数据行,这样就可以允许多个事务同时访问一个表,然而如果一个事务锁住了一个表中许多行,则数据库无法处理那么多锁,只能将所升级到锁住整个表,从而将其他事务锁在外面。这种锁升级现象对并发产生很大影响
    • 大多数事务系统使用SQL标准中定义的4种隔离级别,可串行化是最强的级别,其他每个级别都允许某种程度的不一致读。可串行化无法保证同样条件下多次运行后得到相同的结果,但是得到的结果肯定是对的
    • 如果要保证正确性必须使用可串行化隔离界别,问题是这时系统的灵活性将受到很大的影响,因此要尽量减少串行化以增加系统的吞吐率。你必须决定什么风险是你打算承担的,并在错误和性能之前取得折中。
  • 业务事务 != 系统事务,让业务事务支持ACID属性的最简单办法是在某个系统事务中执行完整流程,但是业务事务通常需要通过多次请求才能完成,用单个系统事务会产生长系统事务,需要我们自己为跨系统业务提供ACID支持
  • 迫不得已才使用分布式事务,如果可以把所有的业务事务都放在单个系统事务中完成,那么就这样做。处理此类问题的首选是乐观离线锁,局限在于只能在提交数据时才发现业务事务将要失败,可能给用户太多打击。另一个使用悲观离线锁,他可以尽早地发现错误,但难以编程实现,而且会降低系统灵活性

离线并发控制