工作单元是维护受业务影响的对象的列表,并维护变化写入和并发问题的解决
大概的意思是说,对多个操作进行打包,记录对象上的所有变化,并在最后提交时一次性将所有变化通过系统事务写入数据库。
工作单元对并发的协调,是依靠聚合根上的乐观离线锁,以及数据库事务的并发控制能力来共同完成的。
Datatable是旧的工作单元,DataTable的AcceptChanges方法。所有修改就保存到数据库了新一代的工作单元DbContext成为数据访问的中心
尽晚打开,尽早释放
1、拦截器
实现类型 (implementationType
) 或类型的任一方法标注了 UnitOfWork
特性的话,要继承IUnitOfWorkEnabled,这三种任一种情况都添加拦截器
IUnitOfWorkEnabled的派生:ApplicationService、BasicRepositoryBase<TEntity> 、DapperRepository<TDbContext>
public override async Task InterceptAsync(IAbpMethodInvocation invocation) { if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method, out var unitOfWorkAttribute)) { await invocation.ProceedAsync(); return; } using (var uow = _unitOfWorkManager.Begin(CreateOptions(invocation, unitOfWorkAttribute))) { await invocation.ProceedAsync(); await uow.CompleteAsync(); } }
创建工作单元
最开始是null,新建一工作单元1,此时为当前工作单元,outer为null,再创建一个工作单元2,此工作单元是当前工作单元,outer为上一个工作单元1,而工作单元1的 outer为null
注意的是,如果工作单元属性为IsReserved、IsDisposed、IsCompleted,工作单元指向outer
当前工作单元不为空,并且不明确requiresNew》创建子工作单元
public IUnitOfWork Begin(AbpUnitOfWorkOptions options, bool requiresNew = false) { Check.NotNull(options, nameof(options)); var currentUow = Current; if (currentUow != null && !requiresNew) { return new ChildUnitOfWork(currentUow); } var unitOfWork = CreateNewUnitOfWork(); unitOfWork.Initialize(options); return unitOfWork; } private IUnitOfWork CreateNewUnitOfWork() { var scope = _serviceScopeFactory.CreateScope(); try { var outerUow = _ambientUnitOfWork.UnitOfWork; var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>(); unitOfWork.SetOuter(outerUow); _ambientUnitOfWork.SetUnitOfWork(unitOfWork); unitOfWork.Disposed += (sender, args) => { _ambientUnitOfWork.SetUnitOfWork(outerUow); scope.Dispose(); }; return unitOfWork; } catch { scope.Dispose(); throw; } }