ASP.NET Core Boilerplate中事务无法回滚问题排查求助
问题根因排查
1. 异常被控制器层捕获吞噬,导致工作单元无法感知错误
ABP 工作单元默认的回滚逻辑是:工作单元范围内未被捕获的异常会触发自动回滚。你在控制器的 try/catch 块中吞掉了应用服务抛出的所有异常,外层的请求级工作单元感知到执行无异常,就会直接提交事务,导致前序删除操作被持久化。
2. 手动开启工作单元的配置错误
你新增的手动工作单元代码没有指定事务参数,可能没有生效:
- 默认
_unitOfWorkManager.Begin()仅会加入当前已存在的 ambient 工作单元(控制器Action默认自带工作单元),不会开启独立事务 - 若未显式指定开启事务,或全局配置关闭了默认事务,操作不会被事务包裹
3. 内层Manager方法开启了独立工作单元
如果你的 _iTS_Emp_Expense_Manager.Delete、_iTS_Audit_Expense_Manager.DeleteByExpenseId 方法上标注了 [UnitOfWork] 特性且设置了独立事务选项,每个方法会单独提交事务,也会导致前序删除操作提前持久化,无法回滚。
修复方案
方案1:控制器捕获异常后手动标记回滚
在控制器的异常捕获块中,显式标记当前工作单元需要回滚:
catch (Exception ex) { string exmptionText = _exemption_AppService.GetTimeTenantUserStamp + ex.Message; ModelState.AddModelError(string.Empty, exmptionText); Logger.Error(exmptionText + ex.StackTrace); // 新增:标记当前工作单元回滚 _unitOfWorkManager.Current?.SetRollbackOnly(); }
应用服务层不需要手动写工作单元的using代码,ABP默认应用服务的public方法自带事务性工作单元,两个删除操作会自动纳入同一个事务。
方案2:手动开启独立事务
如果你需要在应用服务层完全控制事务范围,修改手动工作单元的开启参数,强制开启独立事务:
public void Delete(int id) { // 显式指定开启新事务,第二个参数标识启用事务 using (var unitOfWork = _unitOfWorkManager.Begin(TransactionScopeOption.RequiresNew, true)) { //Delete Expense. _iTS_Emp_Expense_Manager.Delete(id); //Delete Expense Audit. _iTS_Audit_Expense_Manager.DeleteByExpenseId(id); unitOfWork.Complete(); } }
注意此时需要保证Manager层的方法没有开启独立事务,会默认加入当前工作单元。
额外检查项
确认全局配置中没有关闭默认事务,检查模块的 PreInitialize 方法中是否有如下配置,删除或改为true:
// 错误配置会关闭默认事务 Configuration.UnitOfWork.IsTransactionalByDefault = false;
内容的提问来源于stack exchange,提问作者david hosni
相关产品推荐
相关产品推荐

