ABP在其内部实现了工作单元模式,统一地进行事务与连接管理。 其核心就是通过 Castle 的 Dynamic Proxy 进行动态代理,在组件注册的时候进行拦截器注入,拦截到实现了 Unit Of Work 特性的方法进行操作,在执行完方法之后就会关闭掉工作单元。
一、大致处理流程 1 2 3 4 5 6 7 8 9 10 11 12 13 拦截器初始化=>start: 拦截器初始化 注入UOW特性=>operation: 注入UOW特性方法 Begin=>operation: Begin() realAction=>operation: realAction() 真实业务方法 complete=>operation: complete() 执行完成 dispose=>inputoutput: dispose() 销毁并检测 是否销毁条件=>condition: 是否销毁成功? rollback=>operation: 回退结果 e=>end: 结束 拦截器初始化->注入UOW特性->Begin->realAction->complete->dispose->是否销毁条件 是否销毁条件(yes)->e 是否销毁条件(no)->rollback->e 首先UOW拦截器先被注入到了需要UOW的类当中。 ABP在执行标注了UOW的方法(或者是显示式IUnitOfWorkManager包裹的方法)的时候,UOW拦截器首先以这种方式来执行代码:
1 2 3 A[begin]-->B[realaction_method] B-->C[complete method] C-->D[dispose method] UOW拦截器是通过using这种方式调用IUnitOfWork的某个具体实现,这就确保begin 和 dispose也总是会被执行的。Complete()方法不一定会被执行,比如在complete方法被调用前方法的执行产生了异常。
当执行一连串的操作时(A方法->B方法->C方法,假设这三个方法都标注了UnitOfWork特性),ABP在执行A方法前会调用Begin方法创建整个过程中唯一的IUnitOfWork对象,该对象会启动.NET事务。在执行到B,C方法只会创建InnerUnitOfWorkCompleteHandle。
InnerUnitOfWorkCompleteHandle和IUnitOfWork对象的差异在于它不会创建真实的事务。但ABP会调用其complete,以告知ABP其对应的方法以成功完成,可以提交事务。 事务可以回滚的关键关键在于IUnitOfWork对象在被dispose时候会检查complete方法有没有被执行,没有的话就认为这个UOW标注的方法没有顺利完成,从而导致事务的回滚操作。
整个事务的提交是通过第一个UOW(也是唯一个)的complete方法执行时提交的。
二、文件结构说明 文件名称 说明 UnitOfWorkRegistrar 注册拦截器,实现两种默认的UnitOfWork UnitOfWorkInterceptor Unit of Work拦截器,实现以AOP的方式进行注入单元控制 IUnitOfWorkManager UnitOfWork管理对象 UnitOfWorkManager IUnitOfWorkManager默认实现 ICurrentUnitOfWorkProvider 当前UnitOfWork管理对象 CallContextCurrentUnitOfWorkProvider ICurrentUnitOfWorkProvider默认实现 IUnitOfWork 工作单元对象(Begin、SaveChanges、Complete、Dispose) UnitOfWorkBase IUnitOfWork抽象实现类,封装实际操作的前后置操作及异常处理 IActiveUnitOfWork IUnitOfWork操作对象,不包含Begin与Complete操作 IUnitOfWorkCompleteHandle 工作单元完成对象,用于实现继承工作单元功能 InnerUnitOfWorkCompleteHandle IUnitOfWorkCompleteHandle实现之一,用于继承外部工作单元 IUnitOfWorkDefaultOptions UnitOfWork默认设置 UnitOfWorkDefaultOptions IUnitOfWorkDefaultOptions默认实现 UnitOfWorkOptions UnitOfWork配置对象 UnitOfWorkAttribute 标记工作单元的特性 UnitOfWorkFailedEventArgs UnitOfWork的Failed事件参数 UnitOfWorkHelper 工具类 AbpDataFilters 数据过滤相关 DataFilterConfiguration 数据过滤相关 三、注册工作单元 Abp在AbpBootstrapper的private void AddInterceptorRegistrars()方法当中对UnitOfWorkRegistrar 调用了其初始化操作。 初始化操作代码如下: