Abp.AbpException: Did not call Complete method of a unit of work.

       继承自AbpController的一个方法报“Abp.AbpException: Did not call Complete method of a unit of work.”的异常,解决办法,在该方法上加上特性[UnitOfWork(IsDisabled = true)],也就是对该方法禁用工作单元。

abp版本:4.5

原因分析:

       由于所有的AbpController的方法都默认是工作单元方法,而工作单元方法在发生异常时都会触发实现了IUnitOfWorkCompleteHandle接口的类的Dispose()方法。abp中实现了IUnitOfWorkCompleteHandle接口的类有两个,一个是抽象类UnitOfWorkBase,它是所有实现事务控制的类的父类,它里面实现了除了事务控制逻辑以外的其他逻辑,比如Dispose();另一个是类InnerUnitOfWorkCompleteHandle,它是一个非事务的UnitOfWorkCompleteHandle,不会创建真实的事务。

        当我们的方法代码包含事务时(对数据库实体的增、删、改),abp会创建包含事务的IUnitOfWorkCompleteHandle实现类,也就是UnitOfWorkBase的子类,当这个方法出现异常时就会触发UnitOfWorkBase的Dispose()方法,从而抛出异常信息,源码如下:

         当我们的方法不包含事务时(对数据实体只有查询操作或者根本没有数据库的操作),abp会创建InnerUnitOfWorkCompleteHandle,当这个方法出现异常时就会触发InnerUnitOfWorkCompleteHandle的Dispose()方法,但是他的Dispose()里面的代码 HasException()有bug,如下图

即使我们的代码有异常,它还返回的是false,导致它执行了代码

throw new AbpException(DidNotCallCompleteMethodExceptionMessage);

也就是说它屏蔽了我们的所有其他的真实异常信息,不管出现什么异常,都抛出这么个异常信息。

     

        所以当我们的方法没有包含事务时,我们禁用工作单元,那么abp不会创建InnerUnitOfWorkCompleteHandle类,出现异常时也就不会执行那部分代码逻辑,这样我们就能看到真正的异常信息了。还有就是据说abp的Core版本,也就是vNext不存在这个bug,当然能我没有测试,感兴趣的同行可以使用vNext试试,或者新项目的话就不要使用以前的abp了,直接使用vNext更好。

 

Tips:

VS2017Enterprise 调试源码的设置:

 

参考资料:

1.Unit Of Work

2.ABP源码分析十:Unit Of Work

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值