经典的三层分层结构,控制层(Control),服务层(Service),持久层(Repository)应用广泛,在面向服务(SOA)的架构中,配合DI、IOC实现开放灵活的技术架构。
SOA中,Respository面向数据访问,提供访问数据库、文件、或其他业务接口提供持久能力。Service面向业务,提供访问业务功能的接口,使用领域模型描述业务需求,方便产品人员、需求人员和客户沟通理解业务流程。最后,Control面向业务流程整合,提供基于事务的需求实现。
事务,用需求来讲,就是事情要么成功,要么就是没有变化,不能有中间的不正常状态。在数据库事务中,数据库产品已经提供了数据库事务,来保证数据修改删除的事务性,电商支付体系中,也提供了预扣费,消费来保证事务性。
既然事务这么重要,我们应该在哪里控制事务呢?控制层、服务层还是持久层?
按照分而治之的思路,应该是持久层服务持久层的事务,服务层控制服务的事务,控制层控制这个事务,层层管理,内层事务自治的同时,服从外层事务。互相配合,协同工作完成。
理想中的无事务控制流程和生命期是这样的,如下图:
理想中的有事务的流程是这样,简图如下:
但是因为Unity/Spring的系统中,IOC控制着对象的生命周期,图中LifeScope对象对程序员不可见,便会引发集中常见的问题。
1. 完全无视生命期,不进行回收
这种情况下,程序的反应是Respository每次创建数据库连接,直到数据库连接数过多,造成系统宕机。(几乎没人使用的系统除外)
2. 每次创建生命期,等框架自动回收
此时分两类,一种对框架比较了解,能正确配置使用并观察到生命期内对象的回收,此时没有问题。第二种就悲催了,认为框架就应该做好了回收,完全自动化回收,此时完全看抄的度娘上人什么水准了,差的情况,一样会数据库连接数过多,造成系统宕机。
3. 单例服务改为每次创建,降低性能
有时,为了解决单例服务产生的数据库连接问题,连接上已经启动事务等问题,有人把应该为单例的服务配置为每次创建,想依靠服务每次创建,自动创建不懂的数据库连接。姑且不说服务是不是应该单例存在,这样每次创建,就会造成极大的性能开销。